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

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

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

Genericsはパラメトリックなポリモーフィズムの形態であり、.NET やJavaなど、様々な言語に実装されています。C++のテンプレートと同等の機能を持ち合わせています。

Swift

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

Q&A

解決済

2回答

3198閲覧

Swift:プロパティが特定の型のインスタンスでかつプロトコルに適合していることを表現する方法

kuma3

総合スコア60

Generics

Genericsはパラメトリックなポリモーフィズムの形態であり、.NET やJavaなど、様々な言語に実装されています。C++のテンプレートと同等の機能を持ち合わせています。

Swift

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

0グッド

0クリップ

投稿2017/02/16 05:36

編集2017/02/16 07:06

Swiftのプロパティの型表現で題記のような表現を行うにはどのようなコードを書く必要があるでしょうか?
Swiftのバージョンは3.0です。
具体的な例としては下記のような状況でプロトコルViewResizableのviewプロパティがUIViewのインスタンスもしくはサブクラスのインスタンスである場合に、ViewShowableで宣言されているメソッドを実装していることを保証したいです。
ViewResizableを採用するクラスがプロパティとして持つviewはViewShowableを採用しているクラスです。ViewResizableのviewプロパティでその特定のクラスを指定することもできますが、ViewShowableを採用するクラスは様々なクラスが考えられるためそれでは、特定のクラス毎にプロトコルを宣言しなくてはなりません。
そのため、プロパティの記述(ジェネリクス等何かしらの方法)で特定の型のインスタンスでかつプロトコルを採用しているインスタンスを表現することでコードの記述量を減らしたいです。

swift

1protocol ViewShowable { 2 func show() 3 func hide() 4} 5 6protocol ViewResizable { 7 // 下の行はエラーになるが、viewからViewShowableのメソッドを呼び出したい 8 var view: UIView & ViewShowable! { get } 9} 10 11extension ViewResizable { 12 func resizeAndShow() { 13 ビューのフレーム変更コード 14 // showメソッドを呼び出したい 15 view.show() 16 } 17} 18

アドバイスいただけると助かります。
よろしくお願いします。

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

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

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

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

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

fuzzball

2017/02/16 06:39 編集

(質問が編集されていたので削除)
guest

回答2

0

自己解決

プロトコルとプロトコル拡張に型による制約をつけること、さらに利用するクラスでのジェネリクスの活用により可能なことが分かりました。
コードは次の通りです。

swift

1protocol ViewShowable { 2 func show() 3 func hide() 4} 5 6protocol ViewResizable { 7 associatedtype View 8 var view: View! { get } 9} 10 11extension ViewResizable where View: UIView, View: ViewShowable { 12 13 func resizeAndShow() { 14 // 次のコードはエラーにならない 15 print("\(self.view.bounds.size)") 16 // 次のコードも呼び出せる 17 self.view.show() 18 } 19} 20 21 22// UIViewとViewShowableに適合するクラス 23class ShowableView: UIView, ViewShowable { 24 25 func show() { 26 print("show") 27 } 28 29 func hide() { 30 print("hide") 31 } 32} 33 34// ジェネリクスクラスでの宣言 35class Test<T: UIView>: ViewResizable where T: ViewShowable { 36 37 var view: T! 38 39 func test() { 40 // 次のコードを呼び出せる 41 self.resizeAndShow() 42 } 43} 44 45// ジェネリクスクラスの呼び出し時にはジェネリクスの型による制約に適合している具体的なクラスを指定 46let test = Test<ShowableView>() 47

上記のコードはプレイグランドでエラーなく実行できました。
ただし、ジェネリクスクラスではstatic格納型プロパティに対応していないエラー及び@objcが付いているメソッドに対応していないエラーが出たため、UIViewControllerでの採用を検討していた私のコードではこの2つのハードルを越えるのは難しく、利用を断念しました。

投稿2017/02/16 12:49

編集2017/02/16 12:50
kuma3

総合スコア60

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

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

0

swift

1 class CustomView: UIView, ViewShowable { 2 ... 3 } 4 5 protocol ViewResizable { 6 var view: CustomView 7 }

こういうことでしょうか?

投稿2017/02/16 06:42

domonr

総合スコア263

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

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

kuma3

2017/02/16 07:04

イメージとしてはそのような感じです。 しかし、このコードではCustomViewのクラスもしくはCustomViewのサブクラスでなければいけませんよね? うまくジェネリクスの機能を利用して、特定のクラスを指定しなくても大丈夫な方法がないかを考えているのです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問