構造体について
構造体
struct 構造体名 {
var プロパティ名 = 初期値
func メソッド名() {
処理
}
}
以下は例。
struct Item {
var name = "メロン"
var price = 400
func showName() {
print("これは\(name)です")
}
}
// インスタンスの作成
let item = Item()
// メソッドの呼び出し
item.showName() // 結果 これはメロンです
// プロパティの参照
print(item.price) // 結果 400
変数にインスタンスを作成する事なくメソッドを呼び出す事も可能です。
Item().showName() // 結果 これはメロンです
プロパティの値の書き換えは再代入で行う。
item.name = "スイカ"
print(item.name) // 結果 スイカ
プロパティ
ストアドプロパティ
値を保持する為のプロパティ
struct Item {
var name = "メロン" // ストアドプロパティ
// 略
}
let item = Item()
print(item.name) // 結果 メロン
コンピューテッドプロパティ
値を計算する為のプロパティ。
以下のような注意点があります。
- 値が可変である為、変数(var)として定義する必要がある
- 型の指定が必須
struct Item {
var price = 100
// 税込価格を計算するコンピューテッドプロパティ
var priceWithTax:Int {
let result = price * 1.1
return result
}
// 略
}
let item = Item()
print(item.priceWithTax) // 結果 110
内部では関数的な処理が行われているのですが、呼び出しの部分だけ見るとまるでストアドプロパティであるかのように参照することが出来ます。
ちなみに上のコンピューテッドプロパティは以下のようにシンプルに書くことが出来ます。
var priceWithTax:Int {
price * 1.1
}
これはSwiftの、ブロック内({ })の式が一つしかない場合、returnを省略することが出来るというルールを利用した書き方です。
中間変数resultに計算結果を代入する処理を省略し、ブロック内のコードを一行して、上記のルールに則ってreturnを省略したというわけです。
イニシャライズ
インスタンス作成時に構造体の初期処理を行います。
struct Item {
var name: String
var price: Int
init(name: String, price: Int) {
self.name = name
self.price = price
}
// 略
}
let item = Item(name: "メロン", price: 400)
print(item.name) //結果 メロン
インスタンス作成時の引数は以下のようになっていますが、
let item = Item(ラベル名:引数, ラベル名:引数,)
注意する点は、このとき指定しているのでは引数名ではなくラベル名だということです。
先ほどのコードは呼び出しの際に引数名を指定しているように見えますが、
let item = Item(name: "メロン", price: 400)
これはSwiftにラベルを省略すると引数名と同じ名前のラベルが自動で補完されるルールがあります。
先ほどのコードはinit()でラベルを省略しているのでこのルールが適応されているというわけです。
プロトコル
protocol プロトコル名 {
var ストアドプロパティ名: 型名 { get set }
var コンピューテッドプロパティ名: 型名 { get }
func メソッド名()
}
構造体に実装しなければならないプロパティやメソッドの約束事を決める機能です。
あるプロトコルを適合させた構造体は、そのプロトコルに書かれているプロパティやメソッドを実装することが義務付けられます。
エナジードリンクを例に実際に書いてみます。
// プロトコルの定義
protocol energyDrinkProtocol {
var amountOfArginine: Int { get set } // 保有するアルギニンの量を表すプロパティ
func replenishEnergy() // エネルギーを補充するメソッド
}
構造体に適合させてみます。
struct redbull: energyDrinkProtocol {
var amountOfArginine = 125
var amountOfCaffeine = 40
func replenishEnergy() {
print("元気百倍!!")
}
func stimulateTheBrain() {
print("脳が活性化したよ!!")
}
}
energyDrinkProtocolに従い、monster構造体はamountOfArginineプロパティとreplenishEnergy()メソッドを持っておりプロトコルの約束通りの実装です。なのでエラーは出ません。
これがもし、
struct redbull: energyDrinkProtocol {
var amountOfCaffeine = 40
func stimulateTheBrain() {
print("脳が活性化したよ!!")
}
}
のようになっていると、プロトコルとの約束事に反する為エラーが出ます。
まとめると、プロトコルは構造体の仕様書のようなもので、構造体の実装内容をある程度保証する役割があります。