Methods メソッド

Methods are functions that are associated with a particular type. Classes, structures, and enumerations can all define instance methods, which encapsulate specific tasks and functionality for working with an instance of a given type. Classes, structures, and enumerations can also define type methods, which are associated with the type itself. Type methods are similar to class methods in Objective-C. メソッドは、特定の型と結び付けられる関数です。それぞれのクラス、構造体、および列挙は、すべてインスタンスメソッドを定義することができます、それは、ある定められた型のあるインスタンスで働くために特定の作業や機能性をカプセル化します。クラス、構造体、および列挙は、また、型メソッドを定義することができます、それは型それ自身に結び付けられます。型メソッドは、Objective-Cにおけるクラスメソッドに似ています。

The fact that structures and enumerations can define methods in Swift is a major difference from C and Objective-C. In Objective-C, classes are the only types that can define methods. In Swift, you can choose whether to define a class, structure, or enumeration, and still have the flexibility to define methods on the type you create. 構造体と列挙がスウィフトにおいてはメソッドを定義することができるという事実は、CやObjective-Cとの重大な違いです。Objective-Cでは、クラスはメソッドを定義することができる唯一の型です。スウィフトでは、あなたは、クラス、構造体、または列挙を定義すべきかを選択することができます、そしてまだあなたがつくる型でメソッドを定義する柔軟性を持ちます。

Instance Methods インスタンスメソッド

Instance methods are functions that belong to instances of a particular class, structure, or enumeration. They support the functionality of those instances, either by providing ways to access and modify instance properties, or by providing functionality related to the instance’s purpose. Instance methods have exactly the same syntax as functions, as described in Functions. インスタンスメソッドは、特定のクラス、構造体、または列挙のインスタンスに属している機能です。それは、そういったもののインスタンスの機能性を、インスタンスプロパティにアクセスしたり修正したりする方法を提供することで、またはインスタンスの目的と関連がある機能性を提供することでのどちらかで支えます。インスタンスメソッドは、関数と正確に同じ構文を持ちます、関数で記述されるように。

You write an instance method within the opening and closing braces of the type it belongs to. An instance method has implicit access to all other instance methods and properties of that type. An instance method can be called only on a specific instance of the type it belongs to. It can’t be called in isolation without an existing instance. あなたは、インスタンスメソッドを、それが属している型の開始と終わりの波括弧の内部に書きます。あるインスタンスメソッドは、無条件にその型の他のインスタンスメソッドとプロパティの全てへのアクセスを持ちます。インスタンスメソッドは、それが属している型のある特定のインスタンスでだけ呼ばれることができます。それは、単独で既存のインスタンスなしで呼ばれることができません。

Here’s an example that defines a simple Counter class, which can be used to count the number of times an action occurs: 単純なCounterクラスを定義する例がここにあります、それは、ある動作が起こる回数を数えるために使われることができます:

  1. class Counter {
  2. var count = 0
  3. func increment() {
  4. count += 1
  5. }
  6. func increment(by amount: Int) {
  7. count += amount
  8. }
  9. func reset() {
  10. count = 0
  11. }
  12. }

The Counter class defines three instance methods: Counterクラスは、3つのインスタンスメソッドを定義します:

  • increment() increments the counter by 1. increment()は、1だけカウンターを増加させます。
  • increment(by: Int) increments the counter by a specified integer amount. increment(by: Int)は、指定された量の整数でカウンターを増加させます。
  • reset() resets the counter to zero. reset()は、カウンターをゼロに再設定します。

The Counter class also declares a variable property, count, to keep track of the current counter value. Counterクラスはまた、変数プロパティ、countを宣言して、現在のカウンターの値の情報を得続けます。

You call instance methods with the same dot syntax as properties: あなたは、インスタンスメソッドをプロパティと同じドット構文を使って呼び出します:

  1. let counter = Counter()
  2. // the initial counter value is 0(counterの最初の値は、0です)
  3. counter.increment()
  4. // the counter's value is now 1(counterの値は、いま1です)
  5. counter.increment(by: 5)
  6. // the counter's value is now 6(counterの値は、いま6です)
  7. counter.reset()
  8. // the counter's value is now 0(counterの値は、いま0です)

Function parameters can have both a name (for use within the function’s body) and an argument label (for use when calling the function), as described in Function Argument Labels and Parameter Names. The same is true for method parameters, because methods are just functions that are associated with a type. 関数パラメータは、名前(関数の本文内で使うため)と引数ラベル(関数を呼び出すとき使うため)の両方を持つことができます、関数の引数ラベルとパラメータ名で記述されるように。同じことはメソッドパラメータにもあてはまります、なぜならメソッドは、あるひとつの型に結び付けられた単なる関数だからです。

The self Property selfプロパティ

Every instance of a type has an implicit property called self, which is exactly equivalent to the instance itself. You use the self property to refer to the current instance within its own instance methods. ある型のすべてのインスタンスは、暗黙的にselfと呼ばれるプロパティを持ちます、それは、正確にそのインスタンスそれ自身に等しいです。あなたは、selfプロパティを現在のインスタンスに言及するためにそれ自身のインスタンスメソッド内で使います。

The increment() method in the example above could have been written like this: 上の例におけるincrement()メソッドは、このように記述されることができます:

  1. func increment() {
  2. self.count += 1
  3. }

In practice, you don’t need to write self in your code very often. If you don’t explicitly write self, Swift assumes that you are referring to a property or method of the current instance whenever you use a known property or method name within a method. This assumption is demonstrated by the use of count (rather than self.count) inside the three instance methods for Counter. 実際問題として、あなたは頻繁にあなたのコードにselfを書く必要がありません。あなたが明示的にselfを書かないならば、スウィフトは、あなたがメソッド内で既知のプロパティまたはメソッド名を使用するときはいつでも、あなたが現在のインスタンスに属するプロパティまたはメソッドに言及していると仮定します。この仮定は、Counterのための3つのインスタンスメソッド内部での(self.countではなく)countの使用によって示されます。

The main exception to this rule occurs when a parameter name for an instance method has the same name as a property of that instance. In this situation, the parameter name takes precedence, and it becomes necessary to refer to the property in a more qualified way. You use the self property to distinguish between the parameter name and the property name. この規則に対する主な例外は、インスタンスメソッドのパラメータ名がそのインスタンスのプロパティと同じ名前を持つ時に起こります。この状況には、パラメータ名が優先されます、そして、より対象を限定するやり方でプロパティに言及することが必要になります。あなたは、selfプロパティをパラメータ名とプロパティ名を区別するために使います。

Here, self disambiguates between a method parameter called x and an instance property that’s also called x: ここでは、selfは、xと呼ばれるメソッドパラメータと同様にまたxと呼ばれるインスタンスプロパティの間の曖昧さをなくします:

  1. struct Point {
  2. var x = 0.0, y = 0.0
  3. func isToTheRightOf(x: Double) -> Bool {
  4. return self.x > x
  5. }
  6. }
  7. let somePoint = Point(x: 4.0, y: 5.0)
  8. if somePoint.isToTheRightOf(x: 1.0) {
  9. print("This point is to the right of the line where x == 1.0")
  10. }
  11. // Prints "This point is to the right of the line where x == 1.0"(「この点は線x == 1.0の右にある」を出力します)

Without the self prefix, Swift would assume that both uses of x referred to the method parameter called x. self接頭辞なしでは、スウィフトは両方のxの使用がxと呼ばれるメソッドパラメータに言及したものと仮定します。

Modifying Value Types from Within Instance Methods 値型をインスタンスメソッド内から修正する

Structures and enumerations are value types. By default, the properties of a value type can’t be modified from within its instance methods. 構造体と列挙は、値型です。初期状態では、ある値型に属するプロパティは、それのインスタンスメソッド内から修正されることができません。

However, if you need to modify the properties of your structure or enumeration within a particular method, you can opt in to mutating behavior for that method. The method can then mutate (that is, change) its properties from within the method, and any changes that it makes are written back to the original structure when the method ends. The method can also assign a completely new instance to its implicit self property, and this new instance will replace the existing one when the method ends. しかし、あなたがある特定のメソッド内であなたの構造体または列挙のプロパティを修正する必要があるならば、あなたはそのメソッドのために可変挙動を選ぶことができます。このメソッドはそれからそれのプロパティをメソッド内部から変化させること(すなわち変更)ができます、そして、そのメソッドが終了するとき、それが行ったどんな変更も本来の構造体へ書き込まれます。このメソッドはまた、完全に新しいインスタンスをその暗黙のselfプロパティに代入することができます、そして、そのメソッドが終了するとき、この新しいインスタンスは既存のものを置き換えます。

You can opt in to this behavior by placing the mutating keyword before the func keyword for that method: あなたは、そのメソッドのためのfuncキーワードの前にmutatingキーワードを置くことによってこの挙動を取り入れることができます:

  1. struct Point {
  2. var x = 0.0, y = 0.0
  3. mutating func moveBy(x deltaX: Double, y deltaY: Double) {
  4. x += deltaX
  5. y += deltaY
  6. }
  7. }
  8. var somePoint = Point(x: 1.0, y: 1.0)
  9. somePoint.moveBy(x: 2.0, y: 3.0)
  10. print("The point is now at (\(somePoint.x), \(somePoint.y))")
  11. // Prints "The point is now at (3.0, 4.0)"(「ポイントは現在は(3.0, 4.0)です」を出力します)

The Point structure above defines a mutating moveBy(x:y:) method, which moves a Point instance by a certain amount. Instead of returning a new point, this method actually modifies the point on which it’s called. The mutating keyword is added to its definition to enable it to modify its properties. 上のPoint構造体は変更moveBy(x:y:)メソッドを定義します、それは、Pointインスタンスを特定の量だけ動かします。新しい点を返す代わりに、このメソッドは、それが呼び出された点を実際に修正します。mutatingキーワードがその定義に加えられ、それにそのプロパティを修正するのを可能にします。

Note that you can’t call a mutating method on a constant of structure type, because its properties can’t be changed, even if they’re variable properties, as described in Stored Properties of Constant Structure Instances: あなたが定数の構造体型で変更メソッドを呼ぶことができないということに注意してください、なぜなら、定数構造体インスタンスの格納プロパティで記述されるように、そのプロパティは、たとえそれらが変数プロパティであるとしても変わることができないからです。

  1. let fixedPoint = Point(x: 3.0, y: 3.0)
  2. fixedPoint.moveBy(x: 2.0, y: 3.0)
  3. // this will report an error(これは、エラーを報告します)

Assigning to self Within a Mutating Method 変更メソッド内部でselfに代入する

Mutating methods can assign an entirely new instance to the implicit self property. The Point example shown above could have been written in the following way instead: 変更メソッドは、まったく新しいインスタンスを暗黙のselfプロパティに代入することができます。上で示されるPointの例は、その代わりに以下のようにして書かれることができます:

  1. struct Point {
  2. var x = 0.0, y = 0.0
  3. mutating func moveBy(x deltaX: Double, y deltaY: Double) {
  4. self = Point(x: x + deltaX, y: y + deltaY)
  5. }
  6. }

This version of the mutating moveBy(x:y:) method creates a new structure whose x and y values are set to the target location. The end result of calling this alternative version of the method will be exactly the same as for calling the earlier version. 変更moveBy(x:y:)メソッドのこの改作は、それの持つxyの値が目標場所に設定される、新しい構造体を作成します。メソッドのこの代替版を呼ぶ最終結果は、以前の版を呼ぶことと正確に同じです。

Mutating methods for enumerations can set the implicit self parameter to be a different case from the same enumeration: 列挙のための変更メソッドは、暗黙のselfパラメータを同じ列挙からの異なるケース節に設定することができます:

  1. enum TriStateSwitch {
  2. case off, low, high
  3. mutating func next() {
  4. switch self {
  5. case .off:
  6. self = .low
  7. case .low:
  8. self = .high
  9. case .high:
  10. self = .off
  11. }
  12. }
  13. }
  14. var ovenLight = TriStateSwitch.low
  15. ovenLight.next()
  16. // ovenLight is now equal to .high(ovenLightは現在.hightと等しい)
  17. ovenLight.next()
  18. // ovenLight is now equal to .off(ovenLightは現在.lowと等しい)

This example defines an enumeration for a three-state switch. The switch cycles between three different power states (off, low and high) every time its next() method is called. この例は、3つの状態を切り替えるために、ある列挙を定義します。この切替えは、3つの異なる出力状態(offlowhigh)の間を、それのnext()メソッドが呼ばれるたびに循環します。

Type Methods 型メソッド

Instance methods, as described above, are methods that you call on an instance of a particular type. You can also define methods that are called on the type itself. These kinds of methods are called type methods. You indicate type methods by writing the static keyword before the method’s func keyword. Classes can use the class keyword instead, to allow subclasses to override the superclass’s implementation of that method. インスタンスメソッドは、上で記述されるように、あなたが特定の型のインスタンス上で呼び出すメソッドです。あなたは、また、型それ自体の上で呼ばれるメソッドを定義することができます。これらの種類のメソッドは、型メソッドと呼ばれています。あなたは、型メソッドをstaticキーワードをメソッドのfuncキーワードの前に書くことによって示します。クラスは代わりにclassキーワードを使って、サブクラスにスーパークラスのもつそのメソッドの実装をオーバーライドすることを許可できます。

Note 注意

In Objective-C, you can define type-level methods only for Objective-C classes. In Swift, you can define type-level methods for all classes, structures, and enumerations. Each type method is explicitly scoped to the type it supports. Objective-Cでは、あなたはObjective-Cクラスのためにだけ型レベルのメソッドを定義することができます。スウィフトでは、あなたは全てのクラス、構造体、および列挙のために型レベルのメソッドを定義することができます。各型メソッドは、当然ながらそれが支える型にスコープを指定されます。

Type methods are called with dot syntax, like instance methods. However, you call type methods on the type, not on an instance of that type. Here’s how you call a type method on a class called SomeClass: 型メソッドは、インスタンスメソッドの様に、ドット構文で呼ばれます。しかし、あなたは型のメソッドを型の上で呼び出します、その型のインスタンスの上ではなく。あなたが型メソッドをSomeClassと呼ばれるクラスの上で呼び出す方法がここにあります:

  1. class SomeClass {
  2. class func someTypeMethod() {
  3. // type method implementation goes here(型メソッドの実施が、ここにきます)
  4. }
  5. }
  6. SomeClass.someTypeMethod()

Within the body of a type method, the implicit self property refers to the type itself, rather than an instance of that type. This means that you can use self to disambiguate between type properties and type method parameters, just as you do for instance properties and instance method parameters. ある型メソッドの本文内で、暗黙のselfプロパティはその型自身に言及します、その型のインスタンスではありません。これはあなたが型プロパティと型メソッドパラメータの間で曖昧さをなくすためにselfを使うことができることを意味します、ちょうどあなたがインスタンスプロパティとインスタンスメソッドパラメータでするように。

More generally, any unqualified method and property names that you use within the body of a type method will refer to other type-level methods and properties. A type method can call another type method with the other method’s name, without needing to prefix it with the type name. Similarly, type methods on structures and enumerations can access type properties by using the type property’s name without a type name prefix. より一般的に言えば、あなたがある型メソッドの本文内で使うどんな非修飾のメソッドやプロパティ名でも、他の型レベルのメソッドやプロパティに言及します。ある型メソッドは、別の型メソッドを他のメソッドの名前を使って呼ぶことができます、その型名をそれの前に置く必要なしに。同じように、構造体と列挙の型メソッドは、型名前接頭辞なしで型プロパティの名前を使用することによって型プロパティにアクセスすることができます。

The example below defines a structure called LevelTracker, which tracks a player’s progress through the different levels or stages of a game. It’s a single-player game, but can store information for multiple players on a single device. 下の例はLevelTrackerと呼ばれる構造体を定義します、それは、プレイヤーの進み具合をゲームの異なるレベルまたはステージを通して追跡します。それはシングルプレーヤーのゲームです、しかし1つの装置上で複数のプレーヤーのために情報を蓄えることができます。

All of the game’s levels (apart from level one) are locked when the game is first played. Every time a player finishes a level, that level is unlocked for all players on the device. The LevelTracker structure uses type properties and methods to keep track of which levels of the game have been unlocked. It also tracks the current level for an individual player. ゲームが最初にプレイされるとき、ゲームのレベルの全ては鍵をかけられます(レベル1は別として)。プレーヤーがあるレベルを終了するごとに、そのレベルはその装置上の全てのプレーヤーのために鍵を外されます。LevelTracker構造体は、そのゲームのどのレベルが鍵を開けられているかを追跡し続けるために型プロパティとメソッドを使用します。それはまた、個々のプレーヤーのために現在のレベルを追跡します。

  1. struct LevelTracker {
  2. static var highestUnlockedLevel = 1
  3. var currentLevel = 1
  4. static func unlock(_ level: Int) {
  5. if level > highestUnlockedLevel { highestUnlockedLevel = level }
  6. }
  7. static func isUnlocked(_ level: Int) -> Bool {
  8. return level <= highestUnlockedLevel
  9. }
  10. @discardableResult
  11. mutating func advance(to level: Int) -> Bool {
  12. if LevelTracker.isUnlocked(level) {
  13. currentLevel = level
  14. return true
  15. } else {
  16. return false
  17. }
  18. }
  19. }

The LevelTracker structure keeps track of the highest level that any player has unlocked. This value is stored in a type property called highestUnlockedLevel. LevelTracker構造体は、プレーヤーのだれかが鍵を開けた最も高いレベルの情報を得続けます。この値は、highestUnlockedLevelと呼ばれる型プロパティに格納されます。

LevelTracker also defines two type functions to work with the highestUnlockedLevel property. The first is a type function called unlock(_:), which updates the value of highestUnlockedLevel whenever a new level is unlocked. The second is a convenience type function called isUnlocked(_:), which returns true if a particular level number is already unlocked. (Note that these type methods can access the highestUnlockedLevel type property without your needing to write it as LevelTracker.highestUnlockedLevel.) LevelTrackerはまた、2つの型関数を定義してhighestUnlockedLevelプロパティを取り扱います。第一は、unlock(_:)と呼ばれる型関数です、それは、新しいレベルが錠を開けられるときはいつでも、highestUnlockedLevelの値を更新します。第二は、isUnlocked(_:)と呼ばれる便利な型関数です、それは、特定のレベル番号がすでに錠を開けられるならば、trueを返します。(これらの型メソッドは、あなたがそれをLevelTracker.highestUnlockedLevelと書かなくても、highestUnlockedLevel型プロパティにアクセスできる点に注意してください)。

In addition to its type property and type methods, LevelTracker tracks an individual player’s progress through the game. It uses an instance property called currentLevel to track the level that a player is currently playing. その型プロパティと型メソッドに加えて、LevelTrackerは個々のプレーヤーのゲームを通しての進捗を追います。それはcurrentLevelと呼ばれるインスタンスプロパティをプレーヤーが現在プレイしているレベルを追跡するために使います。

To help manage the currentLevel property, LevelTracker defines an instance method called advance(to:). Before updating currentLevel, this method checks whether the requested new level is already unlocked. The advance(to:) method returns a Boolean value to indicate whether or not it was actually able to set currentLevel. Because it’s not necessarily a mistake for code that calls the advance(to:) method to ignore the return value, this function is marked with the @discardableResult attribute. For more information about this attribute, see Attributes. currentLevelプロパティを管理するのを手伝うために、LevelTrackeradvance(to:)と呼ばれるインスタンスメソッドを定義します。currentLevelを更新する前に、このメソッドは要請された新しいレベルがすでに錠を開けられるかどうか調べます。advance(to:)メソッドは、それが実際にcurrentLevelを設定することができたかどうか示すためにブールの値を返します。advance(to:)メソッドを呼び出して戻り値を無視することが必ずしもコードの誤りでないことから、この関数は@discardableResult属性で印されます。この属性についてのさらなる情報として、属性を見てください。

The LevelTracker structure is used with the Player class, shown below, to track and update the progress of an individual player: LevelTracker構造体はPlayerクラスとともに使用され、下で示されるように、個々のプレーヤーの進捗を追跡して更新します:

  1. class Player {
  2. var tracker = LevelTracker()
  3. let playerName: String
  4. func complete(level: Int) {
  5. LevelTracker.unlock(level + 1)
  6. tracker.advance(to: level + 1)
  7. }
  8. init(name: String) {
  9. playerName = name
  10. }
  11. }

The Player class creates a new instance of LevelTracker to track that player’s progress. It also provides a method called complete(level:), which is called whenever a player completes a particular level. This method unlocks the next level for all players and updates the player’s progress to move them to the next level. (The Boolean return value of advance(to:) is ignored, because the level is known to have been unlocked by the call to LevelTracker.unlock(_:) on the previous line.) Playerクラスは、そのプレーヤーの進捗を追うためにLevelTrackerの新しいインスタンスをつくります。それはまたcomplete(level:)と呼ばれるメソッドを提供します、それは、プレーヤーが特定のレベルを完了するときはいつでも呼び出されます。このメソッドは、全てのプレーヤーたちのために次のレベルの錠をあけて、プレーヤーの進捗をかれらを次のレベルへ移動するために更新します。(advance(to:)のブールの戻り値は無視されます、なぜなら、このレベルは前の行でLevelTracker.unlock(_:)呼び出しによってすでに錠を開けられていると分かるからです)。

You can create an instance of the Player class for a new player, and see what happens when the player completes level one: あなたは、新しいプレーヤーのためにPlayerクラスのインスタンスをつくることができて、そのプレーヤーがレベル1を完了するとき、何が起こるか見ることができます:

  1. var player = Player(name: "Argyrios")
  2. player.complete(level: 1)
  3. print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
  4. // Prints "highest unlocked level is now 2"(「最も高い鍵の開いたレベルは現在2です」を出力します)

If you create a second player, whom you try to move to a level that’s not yet unlocked by any player in the game, the attempt to set the player’s current level fails: あなたが二番目のプレーヤーを作成して、あなたがその人をそのゲームにおいてどのプレーヤーによってもまだ錠を開けられていないレベルへ動かそうとするならば、プレーヤーの現在のレベルを決めるその試みは失敗します:

  1. player = Player(name: "Beto")
  2. if player.tracker.advance(to: 6) {
  3. print("player is now on level 6")
  4. } else {
  5. print("level 6 hasn't yet been unlocked")
  6. }
  7. // Prints "level 6 hasn't yet been unlocked"

Properties プロパティ

Subscripts 添え字