私はSwiftのジェネリックで間違っていることを理解しようとしています。
このサンプルの遊び場を作成しました
_import UIKit
public protocol MainControllerToModelInterface : class {
func addGoal()
init()
}
public protocol MainViewControllerInterface : class {
associatedtype MODELVIEW
var modelView: MODELVIEW? {get set}
init(modelView: MODELVIEW)
}
public class MainViewController<M> : UIViewController, MainViewControllerInterface where M : MainControllerToModelInterface {
public weak var modelView: M?
required public init(modelView: M) {
self.modelView = modelView
super.init(nibName: String(describing: MainViewController.self), bundle: Bundle.main)
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
public class Other<C, M> : NSObject where C : MainViewControllerInterface, C : UIViewController, M : MainControllerToModelInterface, C.MODELVIEW == M {
var c : C?
override init() {
let m = M()
self.c = C(modelView: m)
super.init()
}
}
_
行self.c = C(modelView: m)
はこのエラーを示しています_non-nominal type 'C' does not support explicit initialization
_
この他のスタックオーバーフロー 質問から古いXcodeバージョンのこのエラーは、
_cannot invoke initializer for type '%type' with an argument list of type '...' expected an argument list of type '...'
_
しかし、コンパイラーには何が欠けていますか?
私はSwift4/xcode9を使用しています。
更新
提案Use C.init(modelView: m) rather than C(modelView: m)
に従うと、エラーは次のように変わります。
_No 'C.Type.init' candidates produce the expected contextual result type '_?'
_
@ vini-appより、UIViewControllerを削除して動作させるように提案しました。 UIViewControllerが存在するときにコンパイラが満足しない理由はまだわかりません。 Cがその有効なinitメソッドを持っていることを知るだけでは不十分ですか?
「実際の」型ではなく、ジェネリックパラメーターを初期化するときは常に、init
を明示的に使用する必要があります。
self.c = C.init(modelView: m)
C.init(modelView: m)
ではなくC(modelView: m)
を使用します。それで修正されるはずです。
チェックしてください :
あなたのコードでは、この_C : MainViewControllerInterface, C : UIViewController
_のようにしています。
C
をViewControllerとして処理している場合、ViewControllerにはinit(modelView: M)
のようなinit
がありません。
_public class Other<C, M> : NSObject where C : MainViewControllerInterface, M : MainControllerToModelInterface, C.MODELVIEW == M {
var c : C?
override init() {
let m = M()
self.c = C(modelView: m)
super.init()
}
}
_