web-dev-qa-db-ja.com

Swiftで使用される「自己」とは何ですか?

私はSwiftが初めてで、selfが何に使用されているのか、なぜだろうと思っています。

私はクラスや構造でそれを見てきましたが、それらをコードで言及することさえ必要不可欠でもなければ、必要でもありません。彼らは何のために使用され、なぜですか?どのような状況で使用する必要がありますか?

私はこの質問に関する多くの質問と回答を読んできましたが、どれも私の質問に完全に答えることはなく、彼らはいつもJavaのようにthisと比較する傾向があります。

37

また、拡張機能を作成するときにselfを多く使用します。例:

extension Int {
    func square() -> Int {
        return self * self
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func squareMe() {
        self = self * self
    }
}
let x = 3
let y = x.square()  
println(x)         // 3
printlx(y)         // 9

var結果自体を変更したい場合、変更する関数を使用して変更する必要があります

var z = 3

println(z)  // 3

今それを変異させましょう

z.squareMe()

println(z)  // 9

//文字列を使用した別の例を見てみましょう:

extension String {
    func x(times:Int) -> String {
        var result = ""
        if times > 0 {
            for index in 1...times{
                result += self
            }
            return result
        }
        return ""
    }

    // note: when adding mutating in front of it we don't need to specify the return type
    // and instead of "return " whatever
    // we have to use "self = " whatever

    mutating func replicateMe(times:Int){
        if times > 1 {
            let myString = self
            for index in 1...times-1{
                self = self + myString
            }
        } else {
            if times != 1 {
                self = ""
            }
        }
    } 
}


var myString1 = "Abc"
let myString2 = myString1.x(2)

println(myString1)         // "Abc"
println(myString2)         // "AbcAbc"

今すぐmyString1を変更しましょう

myString1.replicateMe(3)

println(myString1)         // "AbcAbcAbc"
26
Leo Dabus

更新:2015年11月24日

はい、それはthis inJavaおよびself inObjectiveと同じです-C、ただしSwiftを使用すると、selfは、プロパティまたはメソッドをクロージャーまたはコード内のプロパティ名を区別します(eginitializers)。そのため、クロージャーから呼び出しを行わない限り、selfを使用せずにクラスコンポーネントのほぼすべてを安全に使用できます。

「自己プロパティタイプのすべてのインスタンスには、selfという暗黙のプロパティがあります。これは、インスタンス自体とまったく同じです。 selfプロパティを使用して、独自のインスタンスメソッド内で現在のインスタンスを参照します。

上記の例のincrement()メソッドは、次のように記述できます。

func increment() {
    self.count++
}

実際には、コードにselfを頻繁に記述する必要はありません。明示的にselfを記述しない場合、Swiftは、メソッド内で既知のプロパティまたはメソッド名を使用するたびに、現在のインスタンスのプロパティまたはメソッドを参照していると想定します。この前提は、Counterの3つのインスタンスメソッド内でcountself.countではなく)を使用することで実証されます。

このルールの主な例外は、インスタンスメソッドのパラメーター名がそのインスタンスのプロパティと同じ名前である場合に発生します。この状況では、パラメーター名が優先され、より限定的な方法でプロパティを参照することが必要になります。 selfプロパティを使用して、パラメーター名とプロパティ名を区別します。

ここで、selfは、xと呼ばれるメソッドパラメーターとxとも呼ばれるインスタンスプロパティを明確に区別します。

抜粋:Apple Inc.“ Swiftプログラミング言語(Swift 2プレリリース)。”


これが Ray Wenderlich Swiftでのselfの使用を推奨する方法です。 =チュートリアル用:

自己の使用

簡潔にするために、Swiftはオブジェクトのプロパティへのアクセスやメソッドの呼び出しを必要としないため、selfの使用を避けてください。

初期化子でプロパティ名と引数を区別する必要がある場合、およびクロージャー式でプロパティを参照する必要がある場合は、selfを使用します(コンパイラーが必要)。

class BoardLocation {
  let row: Int, column: Int

  init(row: Int, column: Int) {
    self.row = row
    self.column = column

    let closure = {
      println(self.row)
    }
  }
}

そして、これは GitHub のアプリケーションのselfに関する推奨事項です。

必要な場合にのみ明示的にselfを参照します

selfのプロパティまたはメソッドにアクセスする場合、デフォルトで暗黙的にselfへの参照を残します。

private class History {
    var events: [Event]

    func rewrite() {
        events = []
    }
}

言語で必要な場合、たとえばクロージャ内、またはパラメータ名が競合する場合にのみ、明示的なキーワードを含めます。

extension History {
    init(events: [Event]) {
        self.events = events
    }

    var whenVictorious: () -> () {
        return {
            self.rewrite()
        }
    }
}

根拠:これにより、自己のキャプチャセマンティクスがクロージャでより際立ち、他の場所での冗長性が回避されます。

60
David Gomez

どのような状況で使用する必要があるか

必須は、ローカル変数の名前がプロパティの名前を覆い隠すときにのみ使用することです。

ただし、style(および読みやすさ)の問題として、私は常にそれを使用します。

  • プロパティ名で使用します。そうしないと、この変数が何であるか不思議に思われます(ローカルで宣言されたパラメータでも着信パラメータでもないため)。

  • このようなメソッドをトップレベルまたはローカル関数と区別するために、関数(メソッド)呼び出しのレシーバーとして使用します。

16
matt

selfが必要な理由についてお話します。

次のようなクラスを定義するとき:

_class MyClass {
    func myMethod()
}
_

クラスオブジェクトを作成しています。はい、クラスもオブジェクトです。

次に、クラスを使用して作成されたインスタンスの数に関係なく、すべてのインスタンスにはそのClassオブジェクトへの参照ポイントがあります。

クラスによって定義されたすべてのインスタンスメソッドがクラスオブジェクトにあり、それらのコピーが1つだけ存在することをイメージできます。

enter image description here

つまり、クラスを使用して作成されたすべてのインスタンスは同じメソッドを共有しています。

クラスオブジェクトのmyMethodであり、すべてのインスタンスで共有されているため、作業中のインスタンスを特定する方法が必要です。

誰かがinstance1.myMethod()と言うとき、「こんにちは!myMethod、あなたの仕事をしてください、_instance1_はあなたが取り組んでいるオブジェクトです」という意味です。

呼び出し元から送られたオブジェクトをどのように参照しますか、selfを使用します。

私が間違っている場合は修正してください、ありがとう。

「実際には、頻繁にコードに自分で書く必要はありません。自分で明示的に記述しない場合、Swiftは、メソッド内で既知のプロパティまたはメソッド名を使用するたびに、現在のインスタンスのプロパティまたはメソッドを参照していると想定します。 "

抜粋:Apple Inc.“ Swiftプログラミング言語。” iBooks。 https://itun.es/tw/jEUH0.l

10
ylin0x81

まず第一に:良い答え、例、説明はすでにここに投稿されていますが、私は何かを指摘しなければなりません:

予約語:self in Swiftはthisと似ていますが、JavaまたはJavascript

@Dave Gomezが正しく引用したように:

型のすべてのインスタンスには、selfと呼ばれる暗黙のプロパティがあります。これは、インスタンス自体とまったく同じです。

そして、ここで主な違いの1つを開始します。

  1. 「すべてのインスタンス」in Swift(少なくとも今のところ)はほとんどEvery-thing
  2. Java(たとえば)でインスタンススコープ内でのみWord thisを使用できる場合、Swiftでほとんど使用できますEvery-where

ここにいくつかの例があります:

//Example 1:
var x="foo"
x.self="bar".self//compiles and run

//Example 2:
print.self(x);//compiles and run

//Example 3:
func myOther(self otherSelf:Person){}
myOther(self: personObject);//compiles and run

//Example 4:
class Foo{
      var bar=""
      init(){
          self.addSome()//this would be the same in Java
      }
      func addSome(){
          //But definitely not this:
          self.self.bar.self.self="some".self.self
      }
}
//Guess what - also compiles and run...
let f=Foo()
print(f.bar)

さらに読みたい場合は、以下を参照してください。 「self.self」がSwiftでコンパイルおよび実行される理由

OPの質問は、それがSwiftにあるものについてであるため、JavaまたはJavascript(ただし、読者がコメントを書く必要がある場合)の説明で読者を退屈させません。

7
Nikita Kurtin

次の記事では、selfについて詳しく説明しています。

Swiftで「self」キーワードを正しく使用する方法


selfは、それ自体を参照するインスタンスのプロパティです。メソッド内のクラス、構造、および列挙インスタンスにアクセスするために使用されます。

型メソッド(static funcまたはclass func)でselfにアクセスする場合、(インスタンスではなく)実際の型を参照します。

Swiftでは、インスタンスのプロパティにアクセスするときにselfを省略できます。

メソッドパラメータがインスタンスプロパティと同じ名前の場合、self.myVariable = myVariableを明示的に使用して区別する必要があります。メソッドパラメータは、インスタンスプロパティよりも優先されることに注意してください。

3
Dmitri Pavlutin

selfはそれ自体を参照するインスタンスのプロパティです。メソッド内のクラス、構造、および列挙インスタンスにアクセスするために使用されます。メソッドパラメータがインスタンスプロパティと同じ名前の場合、self.myVariable =を明示的に使用する必要があります区別するためのmyVariable。メソッドパラメーターはインスタンスプロパティよりも優先されることに注意してください。

    struct Weather {
let windSpeed: Int
  let chanceOfRain: Int
  init(windSpeed: Int, chanceOfRain: Int) {
    self.windSpeed = windSpeed
    self.chanceOfRain = chanceOfRain
  }

  func isDayForWalk() -> Bool {
    let comfortableWindSpeed = 5
    let acceptableChanceOfRain = 30
    return self.windSpeed <= comfortableWindSpeed
      && self.chanceOfRain <= acceptableChanceOfRain
  }

}
// A Nice day for a walk
let niceWeather = Weather(windSpeed: 4, chanceOfRain: 25)  
print(niceWeather.isDayForWalk()) // => true
0
Akbar Khan

クラス関数としてselfを検索中にこの質問(&回答)にたどり着きました。これはInt.selfString.self、またはYourClass.selfのように見えます

以前、私が知る限りでは、彼が言ったとき、ドミトリ・パブルティンの答えだけがこれに触れています:

型メソッド(静的funcまたはクラスfunc)でselfにアクセスする場合、(インスタンスではなく)実際の型を参照します。

selfがこのように使用されると、実際にはSwiftがメタタイプと呼ばれるものを返します。これについてのドキュメントを読むことができます: https:// docs。 Swift.org/Swift-book/ReferenceManual/Types.html#//Apple_ref/Swift/grammar/metatype-type

Swiftrocks.comでのメタタイプの使用に関する非常に素晴らしい 例の記事 もあります。

0
livingtech