web-dev-qa-db-ja.com

非名義型Xは明示的な初期化をサポートしていません

私は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メソッドを持っていることを知るだけでは不十分ですか?

23
Luca Bartoletti

「実際の」型ではなく、ジェネリックパラメーターを初期化するときは常に、initを明示的に使用する必要があります。

self.c = C.init(modelView: m)
35
andyvn22

C.init(modelView: m)ではなくC(modelView: m)を使用します。それで修正されるはずです。

3
rounak

チェックしてください :

あなたのコードでは、この_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()
    }
}
_
1
Vini App