オプションのチェーン接続
日本語を消す 英語を消す下記URLから引用し、日本語訳をつけてみました。
https://docs.swift.org/swift-book/documentation/the-swift-programming-language/optionalchaining
Access members of an optional value without unwrapping.
アンラップせずにオプションの値のメンバーにアクセスします。
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.
Swift のオプションのチェーンは、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
という単一の Int
プロパティがあり、デフォルト値は 1 です。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
の residence
プロパティ値は nil
です。
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.
これにより、Swift はオプションの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
の場合、numberOfRooms
にアクセスできなかったという事実を反映して、このオプションの Int
も nil
になります。 オプションの 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:
Residence
インスタンスを john.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
には、nil
ではなく、実際の Residence
インスタンスが含まれるようになりました。 前と同じオプションのチェーンを使用してnumberOfRooms
にアクセスしようとすると、Int?
が返されるようになります。 これには、デフォルトの numberOfRooms
値 1 が含まれます。
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)."
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.
オプションのチェーンを使用して、複数レベルの深さのプロパティ、メソッド、および添字を呼び出すことができます。 これにより、相互に関連する型の複雑なモデル内のサブプロパティにドリルダウンし、それらのサブプロパティのプロパティ、メソッド、添え字にアクセスできるかどうかを確認できます。
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.
このバージョンの Residence
は、
配列にアクセスするためのショートカットとして、rooms
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
を返し、両方に値がある場合はstreet
と連結されたbuildingNumber
を返し、それ以外の場合は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
が現在 nil
であるため、john.residence
の address
プロパティを設定しようとすると失敗します。
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
が評価されないことを確認するのは簡単ではありません。 以下のリストは同じ割り当てを実行しますが、関数を使用してアドレスを作成します。 この関数は、値を返す前に「関数が呼び出された」ことを出力します。これにより、=
演算子の右側が評価されたかどうかを確認できます。
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:
オプションのチェーンを通じてプロパティを設定しようとする場合も同様です。 上記の「オプションのチェーンによるプロパティへのアクセス」の例では、residence
プロパティが nil
であっても、john.residence
のaddress
値を設定しようとしています。 オプションのチェーンを通じてプロパティを設定しようとすると、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:
添字がオプションのタイプの値(Swift の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]
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
という辞書を定義しています。この辞書には、String
キーを Int
値の配列にマッピングする 2 つのキーと値のペアが含まれています。 この例では、オプションのチェーンを使用して、"Dave"
配列の最初の項目を 91
に設定します。 "Bev"
配列の最初の項目を 1
ずつ増加します。 そして配列の最初の項目を"Brian"
のキーに設定してみます。 testScores
辞書に"Dave"
と"Bev"
のキーが含まれているため、最初の 2 つの呼び出しは成功します。 testScores
辞書に"Brian"
のキーが含まれていないため、3 回目の呼び出しは失敗します。
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
プロパティにアクセスしようとしています。 ここでは、residence
とaddress
のプロパティをチェーンするために、2 つのレベルのオプション チェーンが使用されています。どちらもオプションのタイプです。
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?
です。 したがって、プロパティの基礎となるオプションの型に加えて 2 レベルのオプションの連鎖が適用されている場合でも、john.residence?.address?.street
の戻り値も String?
になります。
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()
メソッドの戻り値であるためです。