質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1093閲覧

プロトコルの{get set}について

hodoru3sei

総合スコア284

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/09/17 15:02

現在
iOSアプリ開発デザインパターン入門
 と言う本を読んでプロトコルについて勉強しているのですが、変数を定義する際にgetやsetが入っているものの違いについてあまりよく理解できなかったので質問させてください。

Swift

1 2protocol Vehicle { 3 ver fuel : Flaot {get set} 4 var fuelEfficient : Float{set} 5 func showFuel() 6} 

このようなコードがありました。ググってみたところget set があるものは準拠先で変数として扱い、setだけのものは準拠先で定数として扱うみたいなことが書いてありました。
protocolないのプロパティにもvarがついていて変数であるのはわかるのになぜ{get set}や{set}をつけて変数か定数かを指定しなければいけないのかよくわかっていません。

そもそもget set をつけるかの違いは変数か定数かだけなのでしょうか?他に重要なことがあったりするのでしょうか教えてください

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2018/09/18 00:36

typoを修正して下さい。コードを書くときはコピペするようにして下さい。
fuzzball

2018/09/18 00:42

「setだけ」ではなく、「getだけ」ではないですか?
guest

回答1

0

ベストアンサー

protocolは{get set}であるか、{get}であるかを要請するだけです。
それが定数でも変数でも要請に従ていれば全く問題がありません。

準拠する側が任意に以下のようにできます。

swift

1struct Car: Vehicle { 2 var fuel: Float 3 var fuelEfficeint: Float = 10 4 5 mutating func drive(mile: Float) { 6 fuel -= mile * fuelEfficeint 7 } 8 9 func showFuel() { 10 print("fuel is", fuel) 11 } 12}

ここで、fuelEfficientが定数ではなく変数となっていますが、protocol Vehicle の要請する{get}「fuelEfficientの値を取得すること」が出来ますので、これで全く問題ありません。

あるいは

swift

1class Car { 2 3 private let full: Float = 1000 4 private var useFuel: Float = 0 5 6 var fuel: Float { 7 get { 8 return full - useFuel 9 } 10 set(newValue) { 11 useFuel -= newValue - fuel 12 useFuel = min(useFuel, full) 13 } 14 } 15 var fuelEfficeint: Float = 10 16 17 18 func drive(mile: Float) { 19 useFuel += mile * fuelEfficeint 20 } 21 22 func showFuel() { 23 print("fuel is", fuel) 24 } 25}

のようにcomputed propertyとすることもできます。

protocolの要請はあくまでも、取得と設定ができるか、あるいは取得ができるかだけであり、その要請に従っていれば、変数であっても定数であってもcomputed propertyであっても関係ありません。


この考えを理解するにはprotocolを「使う側」と「使われる側」に分けて考える必要があります。

以下に使う側から見たprotocolを例示します。

少し難しいかもしれませんが、これが一番わかりやすいと思います。
前提条件として、protocol Vehicleに準拠した型はCarだけではなくそのほかのもの多数存在しているとします。

swift

1// この関数は様々な機械のインスタンスを返します。Vehicle だけどは限りません。 2let anyMachine: Any = getMachine() 3 4// このif文はanyMachineがVehicleに準拠していれば真となり、定数 vehicle にそのインスタンスをVehicleとして代入します。 5// ただし、実際の型が何であるかはわかりません。また、その必要がありません。 6if let vehicle = anyMachine as? Vehicle { 7 8 // vehicleがprotocol Vehicleに準拠していることが確定しているので、showFuel()メソッドが使用可能です。 9 vehicle.showFuel() 10 11 // protocol VehicleはfuelEfficeintへのsetを許していませんので、下のステートメントはエラーとなります。 12 // vehicle.fuelEfficeint = 200 13 14}

このように使う側は実際の型が何であるかはわからないが、protocol Vehicleに準拠したインスタンスであることを調べることでprotocol Vehicleのプロパティやメソッドを使用できるようになります。
この場合、使う側は struct Car の存在を知らなくても全く問題がありません。

投稿2018/09/18 08:11

編集2018/09/18 08:52
MasakiHori

総合スコア3384

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問