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

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

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

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

Q&A

解決済

1回答

492閲覧

swiftのApple公式ドキュメンテーションの見方について

pegy

総合スコア243

Swift

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

0グッド

0クリップ

投稿2020/09/14 03:19

英語自体は苦手ではないのですが、ドキュメンテーションの見方がやはり慣れません。
少しコツや良い解説などがあれば教えていただきたいのですが、例えば、今コードで
String(describing:hoge)というコードを見つけて、通常Int型のイニシャラーザーを使って、型を変換する場合はInt(hoge)なのにどういうことなのかと調べようとドキュメンテーションを引いてみようと思いましした。

Init(describing:hoge)に関するドキュメンテーション

Swift

1//documantation declaration 2//init<Subject>(describing instance: Subject) 3 4//documentation for example 5print(String(describing: p))

例えば、上記の様にdeclarationと具体例が書かれているのですが、どの様に読み取ればいいのかがわかりません。

個別的なドキュメンテーションの見方

1.initはイニシャライザーの呼び出しなので、実際の例では省略OKと解釈していますが、合っていますでしょうか?例えばPHPのドキュメンテーション上、省略していい箇所は[, omit]の様にカッコが気にされていたりするのですが、その様な物がないので、迷っています。
2.<Subject>この括弧書きとSubjectの意味は具体的にどういう意味なのでしょうか?実際の例を見るとStringという型(構造体)を指定している様に見えるのですが・・・
3.describing instance: SubjectここのinstanceSubjectに相当する者は一体。。。実際にinstanceは特に具体例に何もないので省略されている?Subjectは結果的に変換したい値だとは思うのですが、init<Subject>とは同じ値を代入していない様に見えるのですが前半と後半のSubjectは文法説明上、意味が異なるのでしょうか?一般的には対象という意味なのかと思いますが。

###具体的なドキュメンテーションの見方
また、最終的にInt(hoge)となぜ文法的に違う(describing:を付すといういみで)ことをこのdocumentationから読み取ろうとしているのですが、一通り読んでも文字列を作成するためのinit<Subject>(describing instance: Subject)としか読み取れず、ここからだけではなぜInt(hoge)とは違うのかが読み取れなかったのですが、そもそもそういう違いを知るためにdocumentationを見るというアプローチが間違っているのでしょうか?※と言いつつInt()は構造体としての説明しかない(数値列への変換というイニシャライザー的な説明は内容にお見受けしました)ので比較してみるということもできてはいないのですが・・・

少し、最後に説明が下手になったしまい申し訳ございませんが、Int(hoge)String(describing:hoge)の文法的な違い(イニシャライズの方法になぜ違いがあるのか)をdocumentation勉強したいというときに、アプローチ方法がわからなかったということでございます。

非常に基礎的なことで申し訳ございませんがよろしくお願い申し上げます。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Swiftの仕様書の一読をお勧めします。

英語が苦でないなら、面倒でも一度全部読むのが最も効率のよい学習方法だと思います。
Webならswift.orgにあります。
iBookでダウンロードして読むこともできます。
いずれも無料ですし、英文も非常に読みやすく、よくできていると私は思います
A Swift Tourの部分だけでもかなり有用なので、ご一読ください。

1.initはイニシャライザーの呼び出しなので、実際の例では省略OKと解釈していますが、合っていますでしょうか?例えばPHPのドキュメンテーション上、省略していい箇所は[, omit]の様にカッコが気にされていたりするのですが、その様な物がないので、迷っています。

省略OKです。合っています。

let struct = MyStruct.init(param: a)
let struct = MyStruct(param: a)
let struct: MyStruct = .init(param: a)

これらはいずれも同じです。
たしかに[]をつけるような記載の仕方はみかけませんね。

2.<Subject>この括弧書きとSubjectの意味は具体的にどういう意味なのでしょうか?実際の例を見るとStringという型(構造体)を指定している様に見えるのですが・・・

ジェネリクスです。型をパラメータ化する手法で、Subjectとある部分は実際の型名のプレースホルダです。

例えば、Intのaという変数があるとして、String(describing: a)としたとき、Swiftは、aの型がIntであることから、String.init(describing instance: Int)の呼び出しだと理解してくれてそのように処理されます。
Stringの変数を渡したら、String.init(describing instance: String)の呼び出しとして処理されます。実際に全部の型のinitが個別に定義されているということではないのですが、そう思ってもいいような感じに使えるのがジェネリクスのすごい所です。

3.describing instance: SubjectここのinstanceとSubjectに相当する者は一体。。。実際にinstanceは特に具体例に何もないので省略されている?Subjectは結果的に変換したい値だとは思うのですが、init<Subject>とは同じ値を代入していない様に見えるのですが前半と後半のSubjectは文法説明上、意味が異なるのでしょうか?一般的には対象という意味なのかと思いますが。

describingは引数ラベル(argument label)です。
instanceはパラメータ名(parameter name)です。

引数ラベルはその関数を呼ぶ時に使う引数名で、パラメータ名は関数の実装時に使う引数名です。どちらも同じ引数を指します。
可読性を向上するため、同じ引数が二つの名前をもてるようになっています。

たとえば、

func move(to: CGPoint) { if to.x > 0 { 何かする() } }

このmove関数を使うときは、move(to: p)とすればよく、可読性に問題はありません。
しかし、実装側はtoを関数に渡された引数名として使うことになります。to.xは、to自体に点という意味がないため、一見して意味がわかりにくく、可読性に問題があります。

func move(point: CGPoint) { if point.x > 0 { 何かする() } }

この場合、実装は分かりやすくなりましたが、使う側はmove(point: p)としなければならなくて、move(to: p)より可読性が悪いです。

引数ラベルとパラメータ名を定義することで、この問題を回避できます。

func move(to point: CGPoint) { if point.x > 0 { 何かする() } }

引数ラベルをtoとし、パラメータ名をpointにしました。呼ぶ方はmove(to: p)として使えるので分かりやすく、move関数の内部ではpoint.xとして渡されたパラメータにアクセスできるので、可読性がよくなりました。

なお、引数ラベルを省略すると、パラメータ名が引数ラベルになります。
また、引数ラベルに_を指定すると、呼ぶ方はパラメータ名を省略して呼べるようになります。

Int(hoge)としたときに呼ばれるイニシャライザは、init<T>(_ source: T) where T : BinaryIntegerと定義されています。
Tがジェネリクスによる型名です。引数ラベルが_なので、引数名が不要です。(where以降はTがどんな型かを指定しています)

String(describing: hoge)は、引数にdescribingという引数ラベルをもつイニシャライザを呼べと指定しているので、String.init<Subject>(describing instance: Subject)が呼ばれています。

文法的には、単に引数ラベルの定義の違いです。

これらはSwiftの仕様のFunctionsで説明されています。

投稿2020/09/14 08:42

eytyet

総合スコア803

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

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

pegy

2020/09/14 13:42

詳細、ご解説をいただきありがとうございます! 早速ibooksでダウンロードをしましたので、移動中等でも読める環境を整えました。最初に有用とおすすめのあったa Swift tourから読んでみようと思います。 さて、それぞれ関連する部分を調べていたのですが、念のために確認してもいいでしょうか? ① <Subject>について <Subject>はジェネリクスであり、型のパラメーター化であり、汎用的に使えるためのプレースホルダー的な記述と理解しました。これは実際にクラスなどを作るときに様々な型でも汎用的に使える様にする場合にも用いられるし、(実際によく<T>の様なコードを見かけますが、この利用かと思います)、init<Subject>(describing instance: Subject)もSwiftで標準的に実装されているジェネリクスであるという解釈で良いでしょうか?わかりづらくて申し訳ないのですが、文中にあった様にマニュアル上<>で括ることに(省略していいなど)よって特別な意味があるというよりもそもそも文法として<Subject>や<T>などの記法がジェネリクスであると解釈して差し支えないでしょうか? ② describing instanceについて これが単純に引数ラベルとパラメーター名であることに気が付きませんでした、、、ということはつまりこのイニシャライザにおいては、内部的には init (describing instance: hoge) { //instance. XXXX パラメータ名で何か処理が定義 } の様な処理が何かしら定義されているということなのでしょうか? ※どんな定義がされているのかとjump to definitionで見てみると私のxcodeでみると10453行目に public init<Subject>(describing instance: Subject) とだけ書いてあって、期待する上記の様な処理まで見つけることができなかったのですが、そこまではdefinitionではみることができないのでしょうか? ③ Int()やString()といったキャストとの違い 概ね、上記の点以外は理解ができたのですが最後に Int()との違いがよくわから無くなってきました。。。少なくともInt()により数値列に変換するメソッドはジェネリクスを利用している物ではないと整理することができるます。一方で、そもそも文字列にキャストしたいなら、String(hoge)で足りるのに、String(describing:hoge)とする理由もドキュメンテーションを読みながらわからなくなってきてしまいました。。初期化子を利用したりinstance protocolを利用することに意味があるケースがあるということなのでしょうか?
pegy

2020/09/14 13:53

今、いろんな記事を読んでおりましたら最後の③については、オプショナル型の場合コンパイル時に警告なしに出力するという様な記載があり、そこがString(hoge)とString(describing:hoge)の違いなのかもしれません。。documentationからその部分を読み取ることはできないのですが・・・
AOKINAO

2020/09/15 00:05 編集

③ですが、引数の型が同じにもかかわらず、異なる文字列を得たいときなどにも引数ラベルを使えます。  よい例が思い浮かびませんが、String(hoge)でhogeが"\u3042"という文字列だった場合、そのまま"\u3042"という文字列にするのか、Unicodeだと解釈して"あ"という文字列にするのかを選べると便利です。こういうときに(第2引数をつけてそれに応じて変換するのもありですが)、引数ラベルを使えば、そのままの文字列にするのか、引数をUnicodeと解釈するのかを簡単に読み解くことができます。  一方、Int(hoge)の場合、hogeがUInt型の20であれば、Int(hoge)はInt型の20以外の可能性はないので、引数ラベルは特に必要ありません(Swiftの命名規則でも、引数の型を変換するだけのイニシャライザには引数ラベルをつけるべきでは無いと書かれていたと思います)。  せっかくマニュアルを読むのでしたら、命名規則の章を読んでおくとよいかと思います。
eytyet

2020/09/15 00:45 編集

(1) すべて合っていると思います。 (2) これも合っています。Xcodeで定義をみると実装までは出てきません。隠されています。ものによってはオープンソースのSwiftのコードで実装を見ることができるものもあると思います。String(describing:)は多分これです。 https://github.com/apple/swift/blob/8c201f0edceb73a2587941ee42c76e9f13347a15/stdlib/public/core/Mirror.swift#L503 (3) 設計思想でしょうか。 String(hoge)は、 init<T>(_ value: T) where T : LosslessStringConvertible の呼び出しです。別のイニシャライザです。 このように引数ラベルによって、Int型一つを引数にする別のイニシャライザを呼び分けることができます。 これらのイニシャライザの動作の違いが、引数ラベルによってどちらを使うかを指定する意図です。String(describing:)の方は、引数の型(というか準拠しているプロトコル)によって、出力が変わるという説明があると思います。私の場合、これがわざわざ引数ラベルを指定してそちらを呼ぶ理由です。自前のクラスをCustomDebugStringConvertibleプロトコルに準拠させれば、その内容で文字列化できます。もちろんオプショナルのワーニングを消すのにも使えますが、これはXcodeの優秀なワーニング表示や修正機能に従えばそうなります。
pegy

2020/09/15 02:52

To AOKINAO様 コメント有難うございます。そのような利用法ができるんですね。よく分かりました。 また、複数ある場合、引数ラベルで利用法を分けることができるのは確かに便利ですね。言語を作る側は思っていたより、利用者の便のために細かい工夫や考えが施されている事に驚かされました、 宜しくお願い致します!
pegy

2020/09/15 02:56

To eytyet様 有難うございます、殆どの事が解決しました。また、細かい事を知る度に勉強が楽しくなってきました。 実はプロトコルがまだよくわからず、一つまたto studyができたのですが、それが咀嚼できた時に、それに準拠する意味が納得できると信じております。 お力添えに深謝を申し上げます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問