メソッド(方式)
日本語を消す 英語を消す下記URLから引用し、日本語訳をつけてみました。
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/methods
Define and call functions that are part of an instance or type.
インスタンスまたは型の一部である関数を定義して呼び出します。
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.
Swift では構造体と列挙型でメソッドを定義できるという事実が、C や Objective-C との大きな違いです。 Objective-C では、メソッドを定義できる型はクラスだけです。 Swift では、クラス、構造体、列挙型のいずれを定義するかを選択でき、作成した型のメソッドを柔軟に定義できます。
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
クラスを定義する例です。
class Counter {
var count = 0
func increment() {
count += 1
}
func increment(by amount: Int) {
count += amount
}
func reset() {
count = 0
}
}
The Counter
class defines three instance methods:
Counter
クラスは 3 つのインスタンス メソッドを定義します。
increment()
increments the counter by1
.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:
インスタンス メソッドは、プロパティと同じドット構文を使用して呼び出します。
let counter = Counter()
// the initial counter value is 0
counter.increment()
// the counter's value is now 1
counter.increment(by: 5)
// the counter's value is now 6
counter.reset()
// the counter's value is now 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
自己プロパティ
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()
メソッドは次のように記述できます。
func increment() {
self.count += 1
}
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
を明示的に記述しない場合、メソッド内で既知のプロパティまたはメソッド名を使用するときは常に、Swift は現在のインスタンスのプロパティまたはメソッドを参照していると想定します。 この仮定は、Counter
の 3 つのインスタンス メソッド内で count
を(self.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
とも呼ばれるインスタンス プロパティの間の曖昧さを解消します。
struct Point {
var x = 0.0, y = 0.0
func isToTheRightOf(x: Double) -> Bool {
return self.x > x
}
}
let somePoint = Point(x: 4.0, y: 5.0)
if somePoint.isToTheRightOf(x: 1.0) {
print("This point is to the right of the line where x == 1.0")
}
// Prints "This point is to the right of the line where x == 1.0"
Without the self
prefix, Swift would assume that both uses of x
referred to the method parameter called x
.
self
接頭辞がないと、Swift は 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
キーワードを配置します。
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
x += deltaX
y += deltaY
}
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// Prints "The point is now at (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
構造は、Point
インスタンスを一定量だけ移動する、変化する moveBy(x:y:)
メソッドを定義しています。 このメソッドは、新しいポイントを返すのではなく、呼び出されたポイントを実際に変更します。 プロパティを変更できるようにするために、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:
定数構造体インスタンスの保存プロパティで説明されているように、構造体型の定数では、たとえ変数プロパティであってもプロパティを変更できないため、構造体型の定数に対して変更メソッドを呼び出すことはできないことに注意してください。
let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveBy(x: 2.0, y: 3.0)
// 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
の例は、代わりに次の方法で記述することもできます。
struct Point {
var x = 0.0, y = 0.0
mutating func moveBy(x deltaX: Double, y deltaY: Double) {
self = Point(x: x + deltaX, y: y + deltaY)
}
}
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:)
メソッドは、x
と y
の値がターゲットの場所に設定される新しい構造を作成します。 この代替バージョンのメソッドを呼び出した場合の最終結果は、以前のバージョンを呼び出した場合とまったく同じになります。
Mutating methods for enumerations can set the implicit self
parameter to be a different case from the same enumeration:
列挙型のメソッドを変更すると、暗黙的なself
パラメータを同じ列挙型とは異なるケースに設定できます。
enum TriStateSwitch {
case off, low, high
mutating func next() {
switch self {
case .off:
self = .low
case .low:
self = .high
case .high:
self = .off
}
}
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
// ovenLight is now equal to .high
ovenLight.next()
// ovenLight is now equal to .off
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.
この例では、スリーステート スイッチの列挙を定義します。 スイッチは、next()
メソッドが呼び出されるたびに、3 つの異なる電源状態(off
、low
、high
)の間を循環します。
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.
インスタンス メソッドは、上で説明したように、特定の型のインスタンスに対して呼び出すメソッドです。 型自体で呼び出されるメソッドを定義することもできます。 このような種類のメソッドは型メソッドと呼ばれます。 メソッドの func
キーワードの前に static
キーワードを記述することで、型メソッドを示します。 クラスでは代わりに 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 クラスに対してのみ型レベルのメソッドを定義できます。 Swift では、すべてのクラス、構造体、列挙型に対して型レベルのメソッドを定義できます。 各型メソッドは、サポートする型に明示的にスコープされます。
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
というクラスの 型メソッドを呼び出す方法は次のとおりです。
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
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
構造は、型 プロパティとメソッドを使用して、ゲームのどのレベルがロック解除されているかを追跡します。 また、個々のプレイヤーの現在のレベルも追跡します。
struct LevelTracker {
static var highestUnlockedLevel = 1
var currentLevel = 1
static func unlock(_ level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) -> Bool {
return level <= highestUnlockedLevel
}
@discardableResult
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}
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
は、highestUnlockedLevel
プロパティと連携する 2 つの型関数も定義しています。 1 つ目は、unlock(:)
と呼ばれる型関数で、新しいレベルのロックが解除されるたびに、highestUnlockedLevel
の値を更新します。 2 つ目は、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
プロパティの管理を支援するために、LevelTracker
は advance(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
クラスで使用され、個々のプレーヤーの進行状況を追跡および更新します。
class Player {
var tracker = LevelTracker()
let playerName: String
func complete(level: Int) {
LevelTracker.unlock(level + 1)
tracker.advance(to: level + 1)
}
init(name: String) {
playerName = name
}
}
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:)
と呼ばれるメソッドも提供されており、プレーヤーが特定のレベルを完了するたびに呼び出されます。 このメソッドは、すべてのプレイヤーの次のレベルのロックを解除し、プレイヤーの進行状況を更新して次のレベルに移動します。 (前の行のLevelTracker.unlock(_:)
の呼び出しによってレベルのロックが解除されたことがわかっているため、advance(to:)
のブール戻り値は無視されます。)
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 を完了すると何が起こるかを確認できます。
var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// Prints "highest unlocked level is now 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:
2 人目のプレイヤーを作成し、ゲーム内のどのプレイヤーもロックを解除していないレベルに移動しようとすると、プレイヤーの現在のレベルを設定する試みは失敗します。
player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
print("player is now on level 6")
} else {
print("level 6 hasn't yet been unlocked")
}
// Prints "level 6 hasn't yet been unlocked"