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 cannot 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の最初の値は、0です)
counter.increment()
// the counter's value is now 1 (counterの値は、いま1です)
counter.increment(by: 5)
// the counter's value is now 6 (counterの値は、いま6です)
counter.reset()
// 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()
メソッドは、このように記述されることができます:
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
を書かないならば、スウィフトは、あなたがメソッド内で既知のプロパティまたはメソッド名を使用するときはいつでも、あなたが現在のインスタンスに属するプロパティまたはメソッドに言及していると仮定します。この仮定は、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 is 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" (「この点は線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 cannot 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)" (「ポイントは現在は(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 is 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 cannot call a mutating method on a constant of structure type, because its properties cannot be changed, even if they are 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 brand 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は現在.hightと等しい)
ovenLight.next()
// 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つの異なる出力状態(off
、low
とhigh
)の間を、それのnext()
メソッドが呼ばれるたびに循環します。
Type Methods
型メソッド
Instance methods, as described above, are methods that are called 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 may also use the class
keyword to allow subclasses to override the superclass’s implementation of that method.
インスタンスメソッドは、先に述べたように、特定の型のインスタンスの上で呼ばれるメソッドです。あなたは、また、型それ自体の上で呼ばれるメソッドを定義することができます。これらの種類のメソッドは、型メソッドと呼ばれています。あなたは、型メソッドをstatic
キーワードをメソッドのfunc
キーワードの前に書くことによって示します。クラスはまたclass
キーワードを使って、サブクラスにスーパークラスのもつそのメソッドの実装のオーバーライドを許可することができます。
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 is a single-player game, but can store information for multiple players on a single device.
下の例はLevelTracker
と呼ばれる構造体を定義します、それは、プレイヤーの進み具合をゲームの異なるレベルまたはステージを通して追跡します。それはシングルプレーヤーのゲームです、しかし一つの装置上で複数のプレーヤーのために情報を蓄えることができます。
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
はまた、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
プロパティを管理するのを手伝うために、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:)
と呼ばれるメソッドを提供します、それは、プレーヤーが特定のレベルを完了するときはいつでも呼び出されます。このメソッドは、全てのプレーヤーたちのために次のレベルの錠をあけて、プレーヤーの進捗をかれらを次のレベルへ移動するために更新します。(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を完了するとき、何が起こるか見ることができます:
var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// Prints "highest unlocked level is now 2" (「最も高い鍵の開いたレベルは現在2です」を出力します)
If you create a second player, whom you try to move to a level that is not yet unlocked by any player in the game, the attempt to set the player’s current level fails:
あなたが二番目のプレーヤーを作成して、あなたがその人をそのゲームにおいてどのプレーヤーによってもまだ錠を開けられていないレベルへ動かそうとするならば、プレーヤーの現在のレベルを決めるその試みは失敗します:
player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
print("player is now on level 6")
} else {
print("level 6 has not yet been unlocked")
}
// Prints "level 6 has not yet been unlocked" (「レベル6はまだ開錠されていません」を出力します)
Copyright © 2018 Apple Inc. All rights reserved. Terms of Use | Privacy Policy | Updated: 2018-03-29