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

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

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

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

Q&A

解決済

2回答

1520閲覧

定義が何を意味してるのかわからない

Rnabe

総合スコア9

Swift

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

0グッド

0クリップ

投稿2020/06/06 01:16

アプリ開発を本を読んで勉強中の初心者です。
定義の仕方を理解できず、技術書を一冊終えてみたのですが知らない定義方法のオンパレードでネットで調べられるとこは調べたのですが調べ方が悪いのか解決しませんでした。

該当のソースコード

import Foundation enum Flavor:Int16 { case milk_tea case uji_matcha_milk case okinawa_brown_sugar_milk case cassis_raspberry_milk case strawberry_milk var name: String { flavorArray[Int(self.rawValue)] } } var flavorArray = ["Milk tea", "Uji Matcha Milk", "Okinawa brown sugar milk", "Cassis raspberry milk", "Strawberry Milk"] class OrderEntity : Identifiable ,ObservableObject { @Published public var id: String @Published public var flavor: Int16 @Published public var nataDeCoco: Bool public var flavorName: String { Flavor(rawValue: self.flavor)!.name } init( id: String = UUID().uuidString, flavor: Int = 0, nataDeCoco: Bool = true) { self.id = id self.flavor = Int16(flavor) self.nataDeCoco = nataDeCoco } }

わからないコード

var name: String {
flavorArray[Int(self.rawValue)]
}

public var flavorName: String {
Flavor(rawValue: self.flavor)!.name
}

2つの式はおそらくゲッターであると思うのですが、[Int(self.rawValue)]といった定義は初めてで、Flavor(rawValue: self.flavor)!.nameに関しても何をどう定義してるのかわかりません

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

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

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

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

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

guest

回答2

0

こういう時は簡単な例に分解して Playgorund で実行させてみるのがいいかと思います。

Swift

1import UIKit 2 3enum Flavor:Int16 { 4 case milk_tea 5 case uji_matcha_milk 6 case okinawa_brown_sugar_milk 7 case cassis_raspberry_milk 8 case strawberry_milk 9 10 var name: String { 11 flavorArray[Int(self.rawValue)] 12 } 13 14 // MARK: 追加 15 func printSelf() { 16 print(self, "型名は: ", type(of: self)) 17 } 18} 19 20var flavorArray = ["Milk tea", 21"Uji Matcha Milk", 22"Okinawa brown sugar milk", 23"Cassis raspberry milk", 24"Strawberry Milk"] 25 26// flavor の値を .cassis_raspberry_milk にセット 27var flavor: Flavor = .cassis_raspberry_milk 28 29// self を表示させてみる。 30flavor.printSelf() 31 32// flavor の rawValue (Int16での値)を表示 33print(flavor.rawValue) 34 35// flavor.rawVale に対応させた配列の要素を表示 36print(flavorArray[Int(flavor.rawValue)]) 37 38// 上記と同じことを Flavor のメソッドで実行 39print(flavor.name) 40 41// Flavor に引数を与えてインスタンスを作る 42print(Flavor(rawValue: 3)) 43 44// Flavor に引数を与えてインスタンスを作り、name メソッドを実行する 45// Flavor(rawValue:)は失敗のあるイニシャライザ、つまり該当するcaseがなければ nil を返す。 46// 強制アンラップをするために ! をつけている 47print(Flavor(rawValue: 3)!.name) 48 49// case でカバーした範囲外の rawValue を与えてみるとわかりやすい 50print(Flavor(rawValue: 6)?.name) // -> nil 51 52// nil を強制アンラップさせると実行時エラー 53print(Flavor(rawValue: 6)!.name) // -> クラッシュ

投稿2020/06/06 01:56

TsukubaDepot

総合スコア5086

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

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

TsukubaDepot

2020/06/06 04:18 編集

各項目の詳しい説明はTomohiroKumagaiさんが先に回答された通りです。
Rnabe

2020/06/06 04:06

調べる以外にそのような方法もあるとは・・・ 独学でどのやり方がいいのかわからないですが、そうやって教えてくれると本当に助かります。ありがとうございます。
guest

0

ベストアンサー

特に疑問を持たれている2つについて、わかりにくくなるかもしれないですけれど、そこで行われていることを順を追って細かく記載いたしますね。

なお、ピックアップされていたコードの塊はご想像の通り、どちらとも ゲッター で正解です。

[Int(self.rawValue)]

添字構文を使って配列の要素を取得

[Int(self.rawValue)] の外側の [] は、変数 flavorArray の添字 (Subscript) なので、つまり「変数 flavorArrayInt(self.rawValue) 番目の要素を取得」という意味になります。

Raw Value を Int 型へ変換

そして Int(self.rawValue) は「self.rawValueInt 型に変換」です。具体的には self.rawValue の値を Int 型のイニシャライザーに渡して Int 型のインスタンスを作成しています。

列挙型に暗黙定義される Raw Value

self.rawValue は、自分自身の持つ rawValue プロパティーの値です。今回の場合は rawValue の定義が見当たらないように見えますけれど、型の定義が enum Flavor:Int16 になっていて、これは「Int16 型の値で表現できる列挙型 Flavor」という意味になっています。この、Int16 型で表現したときの値が rawValue です。

今回の列挙型 (enum) で言えば、それが取る値は milk_tea, uji_matcha_milk, okinawa_brown_sugar_milk, cassis_raspberry_milk, strawberry_milk ですけれど、これらを Int16 型の数値でも表現できるというのを意味しています。そして今回はその具体的な数値を割り当てるコードが記載されていないので、それぞれ 0 から順番に数値が割り当てられています。

試しに Playground などで Flavor.cassis_raspberry_milk.rawValue の値を見てみると、具体的な数値が得られることが確認できます。

Flavor(rawValue: self.flavor)!.name

Flavor(rawValue: self.flavor)!.name定義 というより 計算式 です。ご想像の通り、着目されていた次の式は ゲッター です。

swift

1public var flavorName: String { 2 Flavor(rawValue: self.flavor)!.name 3}

厳密には、ゲッターを定義する get が省略されていて、省略しないで書くと次のようになります。

swift

1public var flavorName: String { 2 get { 3 return Flavor(rawValue: self.flavor)!.name 4 } 5}

つまり Flavor(rawValue: self.flavor)!.name は「プロパティー flavorName のゲッターが返す値」です。

Flavor 型のインスタンスを生成

ご自身で定義した Flavor 型は、上で紹介した通り「Int16 型の値でも表現可能な列挙型」で、その表現のときに使う Int16 型の値のことを一般に Raw Value と呼びます。その RawValue を使って Flavor 型のインスタンスを作成するイニシャライザーを呼び出しています。

そして、そのイニシャライザーに渡している Raw Value が self.flavor です。このプロパティーは OrderEntity 型に定義してあるものを使っています。

Flavor 型のインスタンスを生成できない場合がある

ここまで (Flavor(rawValue: self.flavor)) で、Flavor 型のインスタンスを Raw Value から生成できたことになるのですけれど、Raw Value は例えば 1000 などの大きな値も表現できるため、ご自身で定義した Flavor 型の範囲 (case で定義した列挙子の数)を超える可能性があります。

超えると「Flavor 型では表現できない場合」が出てくるので、Raw Value を受け取るイニシャライザーは「オプショナル型で値を返し、範囲を超えたときには nil を返す」ようになっています。

Flavor 型のインスタンスを生成できる前提で name を取得

今回は「絶対に範囲を超えない前提」で ! を使って、オプショナル型を 強制案ラップ して、具体的な値を取り出しています。具体的には Flavor? 型の値から Flavor 型の値を取得しています。

続く .name で、そうして得られた Flavor 型の値が持っている name プロパティーを参照しています。

投稿2020/06/06 01:52

編集2020/06/06 01:59
TomohiroKumagai

総合スコア441

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

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

TomohiroKumagai

2020/06/06 02:04

説明だけだと難しいですけれど、TsukubaDepot さんの書いてくださった Playground で試す回答を実際に触りながら、その解説的にこの回答を眺めると理解しやすくなりそうな気がします。
Rnabe

2020/06/06 04:08

本当にありがとうございます。 おそらくこの先調べても解決しなかったと思います。あなたの助けに深い感謝????‍♂️
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問