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

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

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

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

Q&A

解決済

1回答

8002閲覧

genericsを使って異なる型を戻り値とする関数の書き方を教えて下さい。

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

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

0グッド

0クリップ

投稿2020/01/15 01:14

genericsを使って異なる型を戻り値として受け取る関数の書き方を教えて下さい。

現状playgroundで↓なかんじでかいてまして、戻り値をオプショナルでないA型もしくはB型で受け取りたいと思っています。

swift

1import UIKit 2 3enum Type { 4 case a 5 case b 6} 7 8class A { 9 var name: String 10 11 init(name: String) { 12 self.name = name 13 } 14} 15 16class B { 17 var name: String 18 19 init(name: String) { 20 self.name = name 21 } 22} 23 24class D { 25 26 var name: String 27 var arrayOfA: [A] 28 var arrayOfB: [B] 29 30 init(name: String) { 31 self.name = name 32 arrayOfA = [A]() 33 arrayOfB = [B]() 34 } 35} 36 37 38class Test { 39 40 var data: D 41 42 init(dataName: String) { 43 data = D(name: dataName) 44 } 45 46 func getContents<T>(type: Type, index: Int) -> T { 47 switch type { 48 case .a : 49 if data.arrayOfA.isEmpty { fatalError() } // ここは通らないのでクラッシュさせる 50 return data.arrayOfA[index] // <= Cannot convert return expression of type 'A' to return type 'T' 51 case .b : 52 if data.arrayOfA.isEmpty { fatalError() } // ここは通らないのでクラッシュさせる 53 return data.arrayOfB[index] // <= Cannot convert return expression of type 'B' to return type 'T' 54 } 55 } 56} 57 58 59let test = Test(dataName: "test") 60 61test.data.arrayOfA.append(A(name: "1")) 62test.data.arrayOfB.append(B(name: "い")) 63 64let sample = test.getContents(type: .a, index: 0) // <= Generic parameter 'T' could not be inferred 65 66print(type(of: sample), sample) 67 68 69 70

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず僕はAとBに何らかの類似性がない場合はジェネリクスを使うべき場面ではないと考えます。
そのありを無視して、回答としては

関数の方はエラーの出ている両方の行に as! Tを追加してください。

さらに

swift

1let sample = test.getContents(type: .a, index: 0)

この行はコンパイラがsampleの型を確定することが不可能なので

swift

1let sample: A = test.getContents(type: .a, index: 0)

のように型を明示してください。

投稿2020/01/15 03:10

MasakiHori

総合スコア3384

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

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

退会済みユーザー

退会済みユーザー

2020/01/15 03:41

回答ありがとうございます。 もう一度同一の関数で処理するべきか考えてみます。 sampleの型は自明だと思ってたのですが、コンパイラが確定できないからエラーが出ているわけですね。
MasakiHori

2020/01/15 14:13

人間が見ると自明であってもコンパイラはあくまでも任意の型を返す関数としてしか認識しません。 型パラメータは前後のヒントから解決されますので例えば func hoge(_ a: A) という関数があった場合は hoge(test.getContents(type: .a, index: 0)) と利用されると型パラメータがAとして処理されます。 また、 let i: Int = test.getContents(type: .a, index: 0) としても型パラメータがIntとして処理されコンパイルは通ります。 もちろんクラッシュしますがコンパイラはそこまではわかりません。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問