Optional Chaining¶ オプショナル連鎖¶
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil
. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil
, the property, method, or subscript call returns nil
. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil
.
オプショナル連鎖は、現時点でnil
であるかもしれないオプショナル上での、プロパティ、メソッド、および添え字への問い合わせや呼び出しのための処理です。そのオプショナルが値を含むならば、プロパティ、メソッド、または添え字の呼び出しは成功します;そのオプショナルがnil
であるならば、プロパティ、メソッド、または添え字の呼び出しはnil
を返します。複数の問い合わせが一緒に鎖で繋げられることができます、そして連鎖の中のどれかの輪がnil
ならば、その連鎖全体がいさぎよく失敗します。
Note 注意
Optional chaining in Swift is similar to messaging nil
in Objective-C, but in a way that works for any type, and that can be checked for success or failure.
スウィフトにおけるオプショナル連鎖は、どんな型のためにでも働きそして成功か失敗を確認されることができるというようなことを除いて、Objective-Cにおけるnil
にメッセージを送ることに似ています。
Optional Chaining as an Alternative to Forced Unwrapping¶ 強制アンラップに代わるものとしてのオプショナル連鎖¶
You specify optional chaining by placing a question mark (?
) after the optional value on which you wish to call a property, method or subscript if the optional is non-nil
. This is very similar to placing an exclamation point (!
) after an optional value to force the unwrapping of its value. The main difference is that optional chaining fails gracefully when the optional is nil
, whereas forced unwrapping triggers a runtime error when the optional is nil
.
あなたはオプショナル連鎖を、そのオプショナルがnil
で無いならばあなたがプロパティ、メソッド、または添え字を呼び出したいオプショナルの値の後に疑問符(?
)を置くことによって指定します。これは、その値を強制アンラップするためにオプショナルの値の後に感嘆符(!
)を置くことに非常に似ています。大きな違いは、オプショナル連鎖はそのオプショナルがnil
であるとき潔く失敗します、だけれども強制アンラップはそのオプショナルがnil
であるとき実行時エラーの引き金となります。
To reflect the fact that optional chaining can be called on a nil
value, the result of an optional chaining call is always an optional value, even if the property, method, or subscript you are querying returns a non-optional value. You can use this optional return value to check whether the optional chaining call was successful (the returned optional contains a value), or didn’t succeed due to a nil
value in the chain (the returned optional value is nil
).
オプショナル連鎖はnil
値上で呼ばれることができるという事実を反映するために、オプショナル連鎖呼び出しの結果は、たとえあなたが問い合わせているプロパティ、メソッド、または添え字が非オプショナルの値を返すとしても、常にオプショナルの値です。あなたは、このオプショナルの戻り値を使って、オプショナル連鎖呼び出しが成功した(返されたオプショナルが値を含む)か、あるいは連鎖の中のnil
値のために成功しなかった(返されたオプショナルの値がnil
である)かどうか確認することができます。
Specifically, the result of an optional chaining call is of the same type as the expected return value, but wrapped in an optional. A property that normally returns an Int
will return an Int?
when accessed through optional chaining.
具体的には、オプショナル連鎖の呼び出しの結果は、期待される戻り値と同じ型ですが、オプショナルの中にラップされています。通常はInt
を返すプロパティは、オプショナル連鎖を通してアクセスされるときInt?
を返します。
The next several code snippets demonstrate how optional chaining differs from forced unwrapping and enables you to check for success. 次のいくつかのコード切れっぱしは、どのようにオプショナル連鎖が強制アンラップと異なるか、そして成功をどのようにあなたが確認できるかを例示します。
First, two classes called Person
and Residence
are defined:
最初に、Person
とResidence
(個人と邸宅)と呼ばれる2つのクラスが定義されます:
- class Person {
- var residence: Residence?
- }
- class Residence {
- var numberOfRooms = 1
- }
Residence
instances have a single Int
property called numberOfRooms
, with a default value of 1
. Person
instances have an optional residence
property of type Residence?
.
Residence
インスタンスは、numberOfRooms
と呼ばれる省略時の値1
を持つInt
プロパティただひとつを持ちます。Person
インスタンスは、型Residence?
のオプショナルresidence
プロパティを持ちます。
If you create a new Person
instance, its residence
property is default initialized to nil
, by virtue of being optional. In the code below, john
has a residence
property value of nil
:
あなたが新しいPerson
インスタンスをつくるならば、そのresidence
プロパティは、オプショナルである長所によって、省略時でnil
に初期化されます。下記のコードにおいて、john
はnil
のresidence
プロパティ値を持ちます:
- let john = Person()
If you try to access the numberOfRooms
property of this person’s residence
, by placing an exclamation point after residence
to force the unwrapping of its value, you trigger a runtime error, because there’s no residence
value to unwrap:
あなたがこの人のresidence
のnumberOfRooms
プロパティに、その値を強制アンラップするためresidence
の後に感嘆符を置くことによって、アクセスしようとするならば、あなたは実行時エラーを引き起こします、なぜなら、アンラップするresidence
値はないからです:
- let roomCount = john.residence!.numberOfRooms
- // this triggers a runtime error(これは、実行時エラーの引き金となります)
The code above succeeds when john.residence
has a non-nil
value and will set roomCount
to an Int
value containing the appropriate number of rooms. However, this code always triggers a runtime error when residence
is nil
, as illustrated above.
john.residence
が非nil
値を持って、roomCount
を部屋の適当な数を含んでいるInt
値に設定するとき、上のコードは成功します。しかし、residence
がnilの
とき、上で説明するように、このコードは常に実行時エラーの引き金となります。
Optional chaining provides an alternative way to access the value of numberOfRooms
. To use optional chaining, use a question mark in place of the exclamation point:
オプショナル連鎖は、numberOfRooms
の値にアクセスする代わりの方法を提供します。オプショナル連鎖を使用するために、感嘆符の代わりに疑問符を使ってください:
- if let roomCount = john.residence?.numberOfRooms {
- print("John's residence has \(roomCount) room(s).")
- } else {
- print("Unable to retrieve the number of rooms.")
- }
- // Prints "Unable to retrieve the number of rooms."(「部屋の数を取り出すことができない」を出力します)
This tells Swift to “chain” on the optional residence
property and to retrieve the value of numberOfRooms
if residence
exists.
これはスウィフトに、オプショナルのresidence
プロパティの上に「繋げて」、そしてresidence
が存在するならばnumberOfRooms
の値を取り出すように言います。
Because the attempt to access numberOfRooms
has the potential to fail, the optional chaining attempt returns a value of type Int?
, or “optional Int
”. When residence
is nil
, as in the example above, this optional Int
will also be nil
, to reflect the fact that it was not possible to access numberOfRooms
. The optional Int
is accessed through optional binding to unwrap the integer and assign the non-optional value to the roomCount
constant.
numberOfRooms
にアクセスする試みは失敗する可能性があるので、オプショナル連鎖は型Int?
の値、すなわち「オプショナルのInt
」、を返すことを試みます。residence
がnil
のとき、上の例の場合のように、このオプショナルのInt
はまたnil
になり、numberOfRooms
にアクセスすることは可能でなかったという事実を反映します。オプショナルのInt
は、オプショナル束縛を通してアクセスされることで、整数をアンラップして取り出して、その非オプショナル値をroomCount
定数へ割り当てます。
Note that this is true even though numberOfRooms
is a non-optional Int
. The fact that it’s queried through an optional chain means that the call to numberOfRooms
will always return an Int?
instead of an Int
.
たとえnumberOfRooms
が非オプショナルのInt
であるとしても、これが当てはまることに注意してください。それがオプショナル連鎖によって問い合わせられるという事実は、numberOfRooms
への呼び出しが常にInt?
を返すことを意味します、Int
ではなく。
You can assign a Residence
instance to john.residence
, so that it no longer has a nil
value:
あなたはjohn.residence
にResidence
インスタンスを代入することができます、それによってそれはもはやnil
値を持ちません:
- john.residence = Residence()
john.residence
now contains an actual Residence
instance, rather than nil
. If you try to access numberOfRooms
with the same optional chaining as before, it will now return an Int?
that contains the default numberOfRooms
value of 1
:
john.residence
は、今では実際のResidence
インスタンスを含みます、nil
ではなく。あなたが前と同じオプショナル連鎖でnumberOfRooms
にアクセスしようとするならば、それは今では省略時のnumberOfRooms
値の1
を含むInt?
を返します:
- if let roomCount = john.residence?.numberOfRooms {
- print("John's residence has \(roomCount) room(s).")
- } else {
- print("Unable to retrieve the number of rooms.")
- }
- // Prints "John's residence has 1 room(s)."(「ジョンの邸宅には1部屋ある」を出力します)
Defining Model Classes for Optional Chaining¶ オプショナル連鎖のモデル・クラスを定義する¶
You can use optional chaining with calls to properties, methods, and subscripts that are more than one level deep. This enables you to drill down into subproperties within complex models of interrelated types, and to check whether it’s possible to access properties, methods, and subscripts on those subproperties. あなたは、深さ1階層以上であるプロパティ、メソッド、そして添え字への呼び出しでオプショナル連鎖を使うことができます。これはあなたに、相互に関係づけられた型である複雑なモデルの内部の下位情報に掘り下げていくこと、そしてそれらの下位情報上でプロパティ、メソッド、そして添え字にアクセスすることが可能であるかどうか確認することを可能にします。
The code snippets below define four model classes for use in several subsequent examples, including examples of multilevel optional chaining. These classes expand upon the Person
and Residence
model from above by adding a Room
and Address
class, with associated properties, methods, and subscripts.
下のコード切れっぱしは、複数階層のオプショナル連鎖の例を含む以降のいくつかの例のために、4つのモデル・クラスを定義します。これらのクラスは、関連するプロパティ、メソッド、そして添え字とともにRoom
とAddress
クラスを加えることによって、上記のPerson
とResidence
モデルを拡張します。
The Person
class is defined in the same way as before:
Person
クラスは、前の通りに定義されます:
- class Person {
- var residence: Residence?
- }
The Residence
class is more complex than before. This time, the Residence
class defines a variable property called rooms
, which is initialized with an empty array of type [Room]
:
Residence
クラスは、前より複雑です。今度は、Residence
クラスはrooms
と呼ばれる変数プロパティを定義します、それは、型[Room]
の空の配列で初期化されます:
- class Residence {
- var rooms: [Room] = []
- var numberOfRooms: Int {
- return rooms.count
- }
- subscript(i: Int) -> Room {
- get {
- return rooms[i]
- }
- set {
- rooms[i] = newValue
- }
- }
- func printNumberOfRooms() {
- print("The number of rooms is \(numberOfRooms)")
- }
- var address: Address?
- }
Because this version of Residence
stores an array of Room
instances, its numberOfRooms
property is implemented as a computed property, not a stored property. The computed numberOfRooms
property simply returns the value of the count
property from the rooms
array.
Residence
のこの改作がRoom
インスタンスの配列を格納するので、そのnumberOfRooms
プロパティは計算プロパティとして実装されます、格納プロパティではなく。計算numberOfRooms
プロパティは、単にrooms
配列からcount
プロパティの値を返します。
As a shortcut to accessing its rooms
array, this version of Residence
provides a read-write subscript that provides access to the room at the requested index in the rooms
array.
そのrooms
配列にアクセスすることへの近道として、Residence
のこの版は読み出し専用の添え字を提供します、それは、rooms
配列の中の要求されたインデックスでの部屋へのアクセスを提供します。
This version of Residence
also provides a method called printNumberOfRooms
, which simply prints the number of rooms in the residence.
Residence
のこの版もprintNumberOfRooms
と呼ばれるメソッドを提供します、それは、単にその住居の部屋数を出力します。
Finally, Residence
defines an optional property called address
, with a type of Address?
. The Address
class type for this property is defined below.
最終的に、Residence
はaddress
と呼ばれるオプショナルのプロパティを、Address?
の型で定義します。このプロパティのためのAddress
クラス型は、下で定義されます。
The Room
class used for the rooms
array is a simple class with one property called name
, and an initializer to set that property to a suitable room name:
rooms
配列のために使用されるRoom
クラスは、name
と呼ばれる1つのプロパティ、そしてそのプロパティを適切な部屋名に設定するイニシャライザをもつ単純なクラスです:
- class Room {
- let name: String
- init(name: String) { self.name = name }
- }
The final class in this model is called Address
. This class has three optional properties of type String?
. The first two properties, buildingName
and buildingNumber
, are alternative ways to identify a particular building as part of an address. The third property, street
, is used to name the street for that address:
このモデルの中の最後のクラスは、Address
と呼ばれています。このクラスは、型String?
の3つのオプショナルのプロパティを持ちます。最初の2つのプロパティ、buildingName
とbuildingNumber
は、アドレスの一部として特定の建物を同定するそれぞれ代替の方法です。第3のプロパティ、street
は、そのアドレスの通りのために使われます:
- class Address {
- var buildingName: String?
- var buildingNumber: String?
- var street: String?
- func buildingIdentifier() -> String? {
- if let buildingNumber = buildingNumber, let street = street {
- return "\(buildingNumber) \(street)"
- } else if buildingName != nil {
- return buildingName
- } else {
- return nil
- }
- }
- }
The Address
class also provides a method called buildingIdentifier()
, which has a return type of String?
. This method checks the properties of the address and returns buildingName
if it has a value, or buildingNumber
concatenated with street
if both have values, or nil
otherwise.
Address
クラスはまた、buildingIdentifier()
と呼ばれるメソッドを提供します、それは、String?
の戻り型を持ちます。このメソッドは、アドレスのプロパティを調べて、それが値を持つならばbuildingName
を、または両方とも値を持つならばbuildingNumber
に繋げてstreet
を、またはそれ以外ではnil
を返します。
Accessing Properties Through Optional Chaining¶ オプショナル連鎖を通してプロパティにアクセスする¶
As demonstrated in Optional Chaining as an Alternative to Forced Unwrapping, you can use optional chaining to access a property on an optional value, and to check if that property access is successful. 強制アンラップに代わるものとしてのオプショナル連鎖で例示されるように、あなたはオプショナル連鎖を使って、あるオプショナル上でプロパティにアクセスして、そのプロパティへのアクセスが成功したか調べることができます。
Use the classes defined above to create a new Person
instance, and try to access its numberOfRooms
property as before:
上のクラス定義を使って、新しいPerson
インスタンスをつくって、前のようにそのnumberOfRooms
プロパティにアクセスすることを試みてください:
- let john = Person()
- if let roomCount = john.residence?.numberOfRooms {
- print("John's residence has \(roomCount) room(s).")
- } else {
- print("Unable to retrieve the number of rooms.")
- }
- // Prints "Unable to retrieve the number of rooms."(「部屋の数を取り出すことができない」を出力します)
Because john.residence
is nil
, this optional chaining call fails in the same way as before.
john.residence
がnil
であるため、このオプショナル連鎖呼び出しは前と同じやり方で失敗します。
You can also attempt to set a property’s value through optional chaining: あなたはまたプロパティの値をオプショナル連鎖を通して設定することを試みることができます:
- let someAddress = Address()
- someAddress.buildingNumber = "29"
- someAddress.street = "Acacia Road"
- john.residence?.address = someAddress
In this example, the attempt to set the address
property of john.residence
will fail, because john.residence
is currently nil
.
この例において、john.residence
のaddress
プロパティを設定する試みは失敗します、なぜならjohn.residence
が現在nil
だからです。
The assignment is part of the optional chaining, which means none of the code on the right-hand side of the =
operator is evaluated. In the previous example, it’s not easy to see that someAddress
is never evaluated, because accessing a constant doesn’t have any side effects. The listing below does the same assignment, but it uses a function to create the address. The function prints “Function was called” before returning a value, which lets you see whether the right-hand side of the =
operator was evaluated.
この代入はオプショナル連鎖の一部です、それが意味するのは、=
演算子の右手側で評価されるコードは何もないということです。前の例において、someAddress
が決して評価されないというのはわかりやすいとはいえません、なぜならある定数を代入することは、何ら副作用を持たないからです。下でのコード出力は、同じ代入を行います、しかしそれはある関数を使ってアドレスを作成します。この関数は、値を返す前に「Function was called(関数は呼び出された)」を出力します、それはあなたに=
演算子の右手側が評価されたかどうかを確かめさせます。
- func createAddress() -> Address {
- print("Function was called.")
- let someAddress = Address()
- someAddress.buildingNumber = "29"
- someAddress.street = "Acacia Road"
- return someAddress
- }
- john.residence?.address = createAddress()
You can tell that the createAddress()
function isn’t called, because nothing is printed.
あなたは、createAddress()
関数が呼ばれなかったと言うことができます、なぜなら何も出力されなかったからです。
Calling Methods Through Optional Chaining¶ オプショナル連鎖を通してメソッドを呼ぶ¶
You can use optional chaining to call a method on an optional value, and to check whether that method call is successful. You can do this even if that method doesn’t define a return value. あなたはオプショナル連鎖を使って、オプショナルの値の上でメソッドを呼んで、そしてそのメソッド呼び出しが成功しているかどうか調べることができます。たとえそのメソッドが戻り値を定義しないとしても、あなたはこれをすることができます。
The printNumberOfRooms()
method on the Residence
class prints the current value of numberOfRooms
. Here’s how the method looks:
Residence
クラス上のprintNumberOfRooms()
メソッドは、numberOfRooms
の現在の値を出力します。どのようにそのメソッドが見えるかは、ここにあります:
- func printNumberOfRooms() {
- print("The number of rooms is \(numberOfRooms)")
- }
This method doesn’t specify a return type. However, functions and methods with no return type have an implicit return type of Void
, as described in Functions Without Return Values. This means that they return a value of ()
, or an empty tuple.
このメソッドは、戻り型を指定しません。しかし、戻り値のない関数で記述されるように、戻り型のない関数やメソッドは、Void
の暗黙の戻り型を持ちます。これは、それらが値()
、または空のタプルを返すことを意味します。
If you call this method on an optional value with optional chaining, the method’s return type will be Void?
, not Void
, because return values are always of an optional type when called through optional chaining. This enables you to use an if
statement to check whether it was possible to call the printNumberOfRooms()
method, even though the method doesn’t itself define a return value. Compare the return value from the printNumberOfRooms
call against nil
to see if the method call was successful:
あなたがこのメソッドをあるオプショナルの値の上でオプショナル連鎖を使って呼ぶならば、メソッドの戻り値はVoid?
になります、Void
ではなく、なぜならば、オプショナル連鎖を通して呼び出されるとき戻り値は常にオプショナルだからです。これはあなたにif
文をprintNumberOfRooms()
メソッドを呼び出すことが可能か調べるために使うことを可能にします、たとえそのメソッドがそれ自身では戻り値を定義しないとしてもです。printNumberOfRooms
呼び出しからの戻り値をnil
と比較して、そのメソッドがうまく呼び出されたか見てください:
- if john.residence?.printNumberOfRooms() != nil {
- print("It was possible to print the number of rooms.")
- } else {
- print("It was not possible to print the number of rooms.")
- }
- // Prints "It was not possible to print the number of rooms."(「部屋の数を出力することは、可能ではありませんでした。」を出力します)
The same is true if you attempt to set a property through optional chaining. The example above in Accessing Properties Through Optional Chaining attempts to set an address
value for john.residence
, even though the residence
property is nil
. Any attempt to set a property through optional chaining returns a value of type Void?
, which enables you to compare against nil
to see if the property was set successfully:
同じことは、あなたがプロパティをオプショナル連鎖を通して設定しようと試みる場合にも当てはまります。オプショナル連鎖を通してプロパティにアクセスするでの前の例は、あるaddress
値をjohn.residence
に対して設定することを試みます、たとえresidence
プロパティがnil
であるとしてもです。オプショナル連鎖を通してプロパティを設定しようとするあらゆる試みは、型Void?
の値を返します、それは、あなたにnil
と比較することでそのプロパティがうまく設定されたかどうか調べることを可能にします。
- if (john.residence?.address = someAddress) != nil {
- print("It was possible to set the address.")
- } else {
- print("It was not possible to set the address.")
- }
- // Prints "It was not possible to set the address."(「住所を設定することは、可能ではありませんでした。」を出力します)
Accessing Subscripts Through Optional Chaining¶ オプショナル連鎖を通して添え字にアクセスする¶
You can use optional chaining to try to retrieve and set a value from a subscript on an optional value, and to check whether that subscript call is successful. あなたは、オプショナル連鎖を使って、あるオプショナルの値上の添え字から値を取り出したり設定したりすること、そしてその添え字がうまく呼び出されるかどうかを調べることができます。
Note 注意
When you access a subscript on an optional value through optional chaining, you place the question mark before the subscript’s brackets, not after. The optional chaining question mark always follows immediately after the part of the expression that’s optional. あなたがオプショナル連鎖を通してオプショナルの値の上で添え字にアクセスするとき、あなたは添え字の角括弧の前に疑問符を置きます、後ろではなく。オプショナル連鎖の疑問符は、常にオプショナルである式部分の直後に続きます。
The example below tries to retrieve the name of the first room in the rooms
array of the john.residence
property using the subscript defined on the Residence
class. Because john.residence
is currently nil
, the subscript call fails:
下の例は、Residence
クラス上で定義される添え字を使って、john.residence
プロパティのrooms
配列での最初の部屋の名前を取り出そうとします。john.residence
が現在nil
なので、添え字呼び出しは失敗します:
- if let firstRoomName = john.residence?[0].name {
- print("The first room name is \(firstRoomName).")
- } else {
- print("Unable to retrieve the first room name.")
- }
- // Prints "Unable to retrieve the first room name."(「最初の部屋名を取り戻すことができない」を出力します)
The optional chaining question mark in this subscript call is placed immediately after john.residence
, before the subscript brackets, because john.residence
is the optional value on which optional chaining is being attempted.
この添え字呼び出しでのオプショナル連鎖の疑問符は、john.residence
の直後、添え字の角括弧の前に置かれます、なぜなら、john.residence
がオプショナル連鎖が試みられているオプショナルの値であるからです。
Similarly, you can try to set a new value through a subscript with optional chaining: 同じように、あなたはオプショナル連鎖を使う添え字を通して、新しい値の設定を試みることができます:
- john.residence?[0] = Room(name: "Bathroom")
This subscript setting attempt also fails, because residence
is currently nil
.
この添え字設定の試みはまた失敗します、なぜならresidence
が現在nil
だからです。
If you create and assign an actual Residence
instance to john.residence
, with one or more Room
instances in its rooms
array, you can use the Residence
subscript to access the actual items in the rooms
array through optional chaining:
あなたが実際のResidence
インスタンスをつくってjohn.residence
に代入して、そのrooms
配列の中に1つ以上のRoom
インスタンスをもつならば、あなたはResidence
添え字を使って、オプショナル連鎖を通してrooms
配列の実際の項目にアクセスすることができます。
- let johnsHouse = Residence()
- johnsHouse.rooms.append(Room(name: "Living Room"))
- johnsHouse.rooms.append(Room(name: "Kitchen"))
- john.residence = johnsHouse
- if let firstRoomName = john.residence?[0].name {
- print("The first room name is \(firstRoomName).")
- } else {
- print("Unable to retrieve the first room name.")
- }
- // Prints "The first room name is Living Room."(「最初の部屋名は、居間です。」を出力します)
Accessing Subscripts of Optional Type¶ オプショナル型の添え字にアクセスする¶
If a subscript returns a value of optional type—such as the key subscript of Swift’s Dictionary
type—place a question mark after the subscript’s closing bracket to chain on its optional return value:
ある添え字がオプショナル型の値を返すならば ― 例えばスウィフトのDictionary
型のキー添え字 ― 疑問符をその添え字の閉じ括弧の後ろに置いて、そのオプショナルの戻り値の上に連鎖を繋げてください:
- var testScores = ["Dave": [86, 82, 84], "Bev": [79, 94, 81]]
- testScores["Dave"]?[0] = 91
- testScores["Bev"]?[0] += 1
- testScores["Brian"]?[0] = 72
- // the "Dave" array is now [91, 82, 84] and the "Bev" array is now [80, 94, 81](「Dave」配列は現在[91, 82, 84]です、そして「Bev」配列は現在[80, 94, 81]です)
The example above defines a dictionary called testScores
, which contains two key-value pairs that map a String
key to an array of Int
values. The example uses optional chaining to set the first item in the "Dave"
array to 91
; to increment the first item in the "Bev"
array by 1
; and to try to set the first item in an array for a key of "Brian"
. The first two calls succeed, because the testScores
dictionary contains keys for "Dave"
and "Bev"
. The third call fails, because the testScores
dictionary doesn’t contain a key for "Brian"
.
上の例はtestScores
と呼ばれる辞書型を定義します、それは、2つの「キーと値」対を含んでいて、それはString
キーをInt
値を持つ配列と関連づけます。この例は、オプショナル連鎖を使って"Dave"
配列の最初の項目を91
に設定します;それから"Bev"
配列の最初の項目を1
だけ増加します;そしてそれから"Brian"
のキーに対応する配列の最初の項目を設定することを試みます。最初の2つの呼び出しは成功します、なぜなら、testScores
辞書は"Dave"
と"Bev"
のキーを含んでいるからです。3番目の呼び出しは失敗します、なぜなら、testScores
辞書は"Brian"
のキーを含んでいないからです。
Linking Multiple Levels of Chaining¶ 連鎖の複数の階層を結ぶ¶
You can link together multiple levels of optional chaining to drill down to properties, methods, and subscripts deeper within a model. However, multiple levels of optional chaining don’t add more levels of optionality to the returned value. あなたは、オプショナル連鎖の複数の階層を結びつけて、あるモデル内のより深いプロパティ、メソッド、そして添え字に掘り下げていくことができます。しかし、オプショナル連鎖の複数の階層は、返された値にさらにオプショナルの階層を加えません。
To put it another way: 言い換えれば:
- If the type you are trying to retrieve isn’t optional, it will become optional because of the optional chaining. あなたが取り出そうとしている型がオプショナルでないならば、それはオプショナル連鎖であることからオプショナルになります。
- If the type you are trying to retrieve is already optional, it will not become more optional because of the chaining. あなたが取り出そうとしている型がすでにオプショナルならば、それは連鎖であることからさらにオプショナルにはなりません。
Therefore: したがって:
- If you try to retrieve an
Int
value through optional chaining, anInt?
is always returned, no matter how many levels of chaining are used. あなたがオプショナル連鎖を通してInt
値を取り出そうと試すならば、Int?
が常に返されます、どんなに多くの連鎖階層が使われようともです。 - Similarly, if you try to retrieve an
Int?
value through optional chaining, anInt?
is always returned, no matter how many levels of chaining are used. 同じように、あなたがオプショナル連鎖を通してInt?
値を取り出そうと試すならば、Int?
が常に返されます、どんなに多くの連鎖階層が使われようともです。
The example below tries to access the street
property of the address
property of the residence
property of john
. There are two levels of optional chaining in use here, to chain through the residence
and address
properties, both of which are of optional type:
下の例は、john
のresidence
プロパティのaddress
プロパティのstreet
プロパティにアクセスしようとします。ここで使用されるオプショナル連鎖の2つの階層があります、そしてresidence
とaddressプ
ロパティを通り抜けて繋げます、その両方ともオプショナル型です:
- if let johnsStreet = john.residence?.address?.street {
- print("John's street name is \(johnsStreet).")
- } else {
- print("Unable to retrieve the address.")
- }
- // Prints "Unable to retrieve the address."(「住所を取り出すことができない」を出力します)
The value of john.residence
currently contains a valid Residence
instance. However, the value of john.residence.address
is currently nil
. Because of this, the call to john.residence?.address?.street
fails.
john.residence
の値は、現在は有効なResidence
インスタンスを含みます。しかし、john.residence.address
の値は、現在はnil
です。このことから、john.residence?.address?.street
への呼び出しは、失敗します。
Note that in the example above, you are trying to retrieve the value of the street
property. The type of this property is String?
. The return value of john.residence?.address?.street
is therefore also String?
, even though two levels of optional chaining are applied in addition to the underlying optional type of the property.
上の例で、あなたがstreet
プロパティの値を取り出そうとしている点に注意してください。このプロパティの型は、String?
です。john.residence?.address?.street
の戻り値は、したがってまた、String?
です、その下のプロパティのオプショナル型に加えて2つのオプショナル連鎖の階層が適用されるとしてもです。
If you set an actual Address
instance as the value for john.residence.address
, and set an actual value for the address’s street
property, you can access the value of the street
property through multilevel optional chaining:
あなたが実際のAddress
インスタンスをjohn.residence.address
のための値として設定して、そしてアドレスのもつstreet
プロパティのために実際の値を設定するならば、あなたは複数階層のオプショナル連鎖を通してstreet
プロパティの値にアクセスすることができます:
- let johnsAddress = Address()
- johnsAddress.buildingName = "The Larches"
- johnsAddress.street = "Laurel Street"
- john.residence?.address = johnsAddress
- if let johnsStreet = john.residence?.address?.street {
- print("John's street name is \(johnsStreet).")
- } else {
- print("Unable to retrieve the address.")
- }
- // Prints "John's street name is Laurel Street."(「ジョンの街路名は月桂樹通りです」を出力します)
In this example, the attempt to set the address
property of john.residence
will succeed, because the value of john.residence
currently contains a valid Residence
instance.
この例において、john.residence
のaddress
プロパティを設定しようとする試みは成功します、なぜならjohn.residence
の値は現在は有効なResidence
インスタンスを含むからです。
Chaining on Methods with Optional Return Values¶ オプショナルの戻り値をもつメソッド上で連鎖する¶
The previous example shows how to retrieve the value of a property of optional type through optional chaining. You can also use optional chaining to call a method that returns a value of optional type, and to chain on that method’s return value if needed. 前の例は、オプショナル連鎖を通してオプショナルの型のプロパティの値を取り出す方法を示します。あなたはまたオプショナル連鎖を使って、オプショナルの型の値を返すメソッドを呼び出すこと、そして必要ならば、そのメソッドの戻り値の上で連鎖することができます。
The example below calls the Address
class’s buildingIdentifier()
method through optional chaining. This method returns a value of type String?
. As described above, the ultimate return type of this method call after optional chaining is also String?
:
下の例は、オプショナル連鎖を通してAddress
クラスのbuildingIdentifier()
メソッドを呼び出します。このメソッドは、型String?
の値を返します。先に述べたように、オプショナル連鎖の後ろのこのメソッド呼び出しの最終的な戻り型は、また、String?
です:
- if let buildingIdentifier = john.residence?.address?.buildingIdentifier() {
- print("John's building identifier is \(buildingIdentifier).")
- }
- // Prints "John's building identifier is The Larches."(「ジョンの建物名は月桂樹です」を出力します)
If you want to perform further optional chaining on this method’s return value, place the optional chaining question mark after the method’s parentheses: あなたがこのメソッドの戻り値の上でさらにオプショナル連鎖を実行したいならば、メソッドの丸括弧の後にオプショナル連鎖の疑問符を置いてください:
- if let beginsWithThe =
- john.residence?.address?.buildingIdentifier()?.hasPrefix("The") {
- if beginsWithThe {
- print("John's building identifier begins with \"The\".")
- } else {
- print("John's building identifier doesn't begin with \"The\".")
- }
- }
- // Prints "John's building identifier begins with "The"."(「ジョンの建物名は「月」で始まります」を出力します)
Note 注意
In the example above, you place the optional chaining question mark after the parentheses, because the optional value you are chaining on is the buildingIdentifier()
method’s return value, and not the buildingIdentifier()
method itself.
上の例で、あなたは丸括弧の後にオプショナル連鎖の疑問符を置きます、なぜなら、あなたがその上に連鎖しているオプショナルの値はbuildingIdentifier()
メソッドの戻り値であって、buildingIdentifier()
メソッドそれ自体ではないからです。