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

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

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

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

Q&A

解決済

1回答

408閲覧

構造体内で同じ型を返り値を返す

pegy

総合スコア243

Swift

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

0グッド

0クリップ

投稿2020/08/13 08:56

編集2020/08/13 10:46

(環境)
xcode:11.3
version 5.1.3

(参考文献)
詳解 Swift 第5版
著者 萩原剛志
発行者 SBクリエイティブジャブ式会社
76ページ

上記の文献を参考にしながらSwiftを学んでおり、構造体のメソッドの箇所で以下の様なコードがございました。
//ここです
という箇所でコメントあるとしている箇所が理解できないのですが、Time構造体を作っているのですが、その中のメソッドの返り値がTime型になっています。

何か、定義している中で自分自身を返り値にしていることでループしている様な印象があり、どの様な意味があるのかがわからないのですが、ここでTime型を返り値にしているのは具体的にどの様な意味があるのでしょうか?
(実際にここでTime型で返すというのがどの様な型を指定しているのかということがコード上ピントこないからという疑問なのかもしれません)

また、少し蛇足になるのですが、//三項演算とコメントアウトしている箇所はtrueもfalseも同じ結果を返すので、コードとしてあまり意味がないと思うのですが、思慮がたりていないのでしょうか。。。

よろしくお願い申し上げます。

swift

1struct Time { 2 let hour, min: Int 3 4 func advanced(min:Int) -> Time { //ここです 5 var m = self.min + min 6 var h = self.hour 7 8 if m >= 60 { 9 h = (h + m / 60) % 24 10 m %= 60 11 } 12 return Time(hour:h, min: m) 13 } 14 15 func toString() -> String { 16 let h = hour < 10 ? " (hour)":"(hour)" // 三項演算 17 let m = min < 10 ? "0(min)":"(min)" 18 return h + ":" + m 19 } 20}

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

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

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

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

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

guest

回答1

0

ベストアンサー

何か、定義している中で自分自身を返り値にしていることでループしている様な印象があり、どの様な意味があるのかがわからないのですが、ここでTime型を返り値にしているのは具体的にどの様な意味があるのでしょうか?

p. 76 に記述してある通り、advanced(min:)は「指定した経過時間後の新しい時刻を返す」、つまり新しい TIme型 の構造体を返すため、return の戻り値が Time型 のインスタンスとなっています。

例題にもありますが、

Swift

1let t1 = Time(hour: 22, min: 45) 2let t2 = t1.advanced(min: 10)

とある通り、t2t1の時刻に「10分」が加算された新しいインスタンスが入っています。

ちなみに、戻り値が Time型 なので、以下のようなことも可能です(メソッドチェーン)。

Swift

1let t3 = t1.advanced(min: 10).advanced(min: 20)

このようにすると、t1 の時刻に10分加算し、さらに20分加算された時刻の新しいインスタンスが t3 に入ります。

また、少し蛇足になるのですが、//三項演算とコメントアウトしている箇所はtrueもfalseも同じ結果を返すので、コードとしてあまり意味がないと思うのですが、思慮がたりていないのでしょうか。。。

時刻が1桁の時に、隙間を入れるための空白が入っています。
つまり、

Swift

1let h = hour < 10 ? "(hour)":"(hour)" // 三項演算

ではなく、

Swift

1let h = hour < 10 ? " (hour)":"(hour)" // 三項演算

が正解になります。

他にもタイプミスがありましたので、合わせて指摘しておきますのでご確認ください。

Swift

1struct Time { 2 let hour, min: Int 3 4 func advanced(min:Int) -> Time { //ここです 5 var m = self.min + min 6 //var h = self.hour + hour 7 var h = self.hour 8 9 if m >= 60 { 10 h = (h + m / 60) % 24 11 m %= 60 12 } 13 return Time(hour:h, min: m) 14 } 15 16 func toString() -> String { 17 //let h = hour < 10 ? "(hour)":"(hour)" // 三項演算 18 let h = hour < 10 ? " (hour)":"(hour)" // 三項演算 19 //let m = min < 10 ? "0(hour)":"(hour)" 20 let m = min < 10 ? "0(min)":"(min)" 21 22 return h + ":" + m 23 } 24}

投稿2020/08/13 09:45

TsukubaDepot

総合スコア5086

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

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

pegy

2020/08/13 11:03

コメントをいただき誠にありがとうございます。 >つまり新しい Time型 の構造体を返すため、return の戻り値が Time型 のインスタンスとなっています。 この点については return Time(hour:h, min: m)を指してのことと理解いたしました。 やはり、どうしても構造体や型に関する基本的なことが腹落ちしないのですが、ここでいうTime構造体であるということはどういうことなのでしょうか? 例えば、標準で供えられているString型であるなどはStruct String{}の中で ・ダブルクオテーションで囲まれた値である ・加算演算子であれば、"1"+"1"でも2ではなく"11"として結合して返す(これがStringではなく+という演算子の型に定義されていたら申し訳ございません、私の誤認です) など、Stringという型であることがその構造体に性格を表す様な内容がプロパティとして存在しているのかと思います。 では、ここでTimeという構造体を作ったとして、ここでいうTime型とはどういう性格を有しているものと言えるのでしょうか?メソッドを除いたら、以下のものしか残らないため、インスタンスプロパティのhourとminがInt型であるということだけがこのTime構造体の特徴なのでしょうか? struct Time { let hour, min: Int } 仮にそういうことであれば、return Time(hour:h, min: m)の戻り値がTime型であれば 1. struct Time { let hour, min: Int }がTime型の構造体の特徴である 2.その中のメソッドとして-> Timeで返すことは 3.結果として、return Time(hour:h, min: m)はInt型で返すことを意味している 4.また、別の視点として、構造体の中では自分自身を含む構造体を返すことができる特徴を持っている (今回で言えば、Time型を作っているのに、その中でTime型を返り値とする様な設定が可能) と解釈することができるのでしょうか? とても的外れなことを申し上げていたら申し訳ございません。 これまでクラスなどでも返り値に自分自身を返すなどは見たことがないので、とても不思議に思い、根底から考えていたところでございます。 よろしくお願い申し上げます。
TsukubaDepot

2020/08/13 21:04

> ・加算演算子であれば、"1"+"1"でも2ではなく"11"として結合して返す(これがStringではなく+という演算子の型に定義されていたら申し訳ございません、私の誤認です) 演算子については、struct String の中で + 演算子を定義してあると思います。 > では、ここでTimeという構造体を作ったとして、ここでいうTime型とはどういう性格を有しているものと言えるのでしょうか?メソッドを除いたら、以下のものしか残らないため、インスタンスプロパティのhourとminがInt型であるということだけがこのTime構造体の特徴なのでしょうか? いえ、メソッドを除いてはいけないと思います。 メソッドを含め、それが TIme 構造体というものだからです。 Time 構造体は、時、分だけでなく、「任意の分を加算することができるメソッドを持った」構造体です。 なので、 > 1. struct Time { let hour, min: Int }がTime型の構造体の特徴である プロパティだけに限定する必要はないかと思います。 > 3.結果として、return Time(hour:h, min: m)はInt型で返すことを意味している いえ、Time型で返しています。 > 4.また、別の視点として、構造体の中では自分自身を含む構造体を返すことができる特徴を持っている 構造体でなくとも、class でも同じです。 構造体とかclass とか考えずに、「型」と考えれば、いかなる構造体やclassも定義済みである任意の型を返すことが可能です。 > (今回で言えば、Time型を作っているのに、その中でTime型を返り値とする様な設定が可能) と解釈することができるのでしょうか? 特別に設定しているのではなく、「言語仕様として」戻り値として任意の型を返せます。 > これまでクラスなどでも返り値に自分自身を返すなどは見たことがないので、とても不思議に思い、根底から考えていたところでございます。 自分自身を返す型はたくさんあるかと思います。正確には自分自身ではなく、自身と同じ型かとおもいます。 Int型でInt型を返すメソッドは全て自身と同じ型を返しますし、Int型にもString型など違う型を返すメソッドもあったりします。
pegy

2020/08/14 01:41

詳細ご回答いただきありがとうございます。 最後に一つだけ念のために確認なのですが、メソッドも含めてstruct Time{}がTime型であるとすれば、その中にTime型を返すメソッドが定義されていてもループ(循環)せずに問題はないという解釈で問題がないのでしょうか?実際におっしゃる通り、Int型の中でInt型で返すこともある様ですが、りんごという構造(型)を作っている中で、色を赤いというプロパティをりんご型で返すというのはいや、ここでりんご型を決めているのに循環参照してまっせ〜と一般論理として突っ込みたくなりそうなところですが、言語仕様としてあり得ることなのですね・・・ それがlet hour, min: Int だけであれば、先に宣言済みなのでそのあとからなら参照できるという理屈であればわかりやすかったのですが、慣れが必要なのかもしれません。。。
TsukubaDepot

2020/08/14 03:35

イニシャライザに値を渡してインスタンスを作っただけなので、循環参照には当たらないと思っています。 もっとも、たとえば advance() の戻り値が return Time(hour:h, min: m).advanced(min: 10) となっている場合には循環参照になるためエラーとなります(コンパイラがエラーを出します)。 また、Time構造体の中のプロパティとして TIme型を宣言してもエラーとなります。
pegy

2020/08/14 06:26

コメントありがとうございます。承知をいたしました。 概ね理解することができたと思います。 いつもお力添えをいただき深謝申し上げます。 よろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問