1

別のプロトコルに準拠するいくつかの型オブジェクトを管理するプロトコルを指定したいと考えています。このような:

// Specify protocol
protocol ElementGenerator {
    func getElements() -> [Element]
}
protocol Element {
    // ...
}

// Implement
class FooElementGenerator: ElementGenerator {
    func getElements() -> [FooElement] {
        // Generate elements here
        return [FooElement()]
    }
}
class FooElement {
    // ...
}

これをコンパイルしようとすると、エラーが発生します。

Type 'FooElementGenerator' does not conform to protocol 'ElementGenerator'

func getElements() -> [FooElement]候補が一致しないタイプの を持っていることを示唆して() -> [FooElement]いますが、代わりに を期待してい() -> [Element]ます。

この種のエラーはどのように修正できますか?

アップデート:

このソリューションは機能しているようです:

protocol ElementGenerator {
    typealias T:Element

    func getElements() -> [T]
}

protocol Element {
    // ...
}


class FooElementGenerator: ElementGenerator {
    typealias T = FooElement

    func getElements() -> [T] {
        return [T()]
    }
}

class FooElement: Element {
    // ...
}

しかし、次のような変数を作成しようとすると:

let a: ElementGenerator = FooElementGenerator()

新しいエラーが表示されます:

Protocol 'ElementGenerator' can only be used as a generic constraint because it has Self or associated type requirements
4

2 に答える 2

1

プロトコル メソッドを実装する場合、戻り値の型は同じでなければなりませんが、次のように子クラス オブジェクトを返すことができます。

protocol ElementGenerator {
    func getElements() -> [Element]
}

//@objc for bridging in objective C
@objc protocol Element {
    // ...
}

// Implement
class FooElementGenerator: NSObject,ElementGenerator {

    override init() {
        super.init();
        //--
        let fooElements:[FooElement] = self.getElements() as! [FooElement]
    }

    func getElements() -> [Element] {
        // Generate elements here
        return [FooElement()]
    }
}

class FooElement:NSObject, Element {
    // ...
    override init() {
        super.init();
        //--
        NSLog("FooElement init");
    }
}
于 2015-08-31T07:58:51.787 に答える
0

ElementGenerator2 番目のケースのエラー メッセージは、「関連付けられた型」で定義したために表示されます。これは、型に制約を与える場合にのみ使用できることを意味します。

たとえば、一般的なElementGenerator値に対して関数を定義する必要がある場合は、次のように記述できます。

func f<T1:ElementGenerator>(elemGenerator:T1) -> Element {
  return elemGenerator.getElements()[0]
}

var a : Element = FooElementGenerator()
var b : Element = BarElementGenerator()

var x : Element = f(a)
var y : Element = f(b)

var z : FooElement = f(a) as! FooElement
于 2015-08-31T08:49:52.393 に答える