4

Int以下のように拡張機能を書きました。

extension Int {
    func squared () -> Int {
        return self * self
    }
}

print(10.squared()) // works

上記のコードは機能します。IntegerTypeここで、Int、UInt、Int64 などがすべて準拠するようにプロトコルを拡張したいと考えています。私のコードは以下の通りです。

extension IntegerType {

    func squared () -> IntegerType { // this line creates error

        return self * self

    }
}

エラーが発生します:

プロトコル 'IntegerType' は、自己型または関連付けられた型の要件があるため、一般的な制約としてのみ使用できます

私はすでにこの質問とそのビデオとこの質問を見ましたが、まだ理解できませんでした. associatedTypeこの場合はあるSelfが、点をつなぐことができなかったものがあることだけを理解しました。自分の知識不足Genericsも一因のような気もしますが…

誰かがこの件について少し詳しく説明できますか?なぜ拡張機能がエラーを作成するのですか?

4

2 に答える 2

7

戻ればいいだけSelf

編集/更新:

注: Numeric Protocol を拡張する Swift 4 では、すべての数値型 (Integer & FloatingPoint) を拡張できます。

スイフト4

extension Numeric {
    func squared() -> Self {
        return self * self
    }
}

スイフト3

extension Integer {
    func squared() -> Self { 
        return self * self
    }
}
于 2016-09-05T23:44:45.760 に答える
3

関数の戻り値の型は具象のみTypeです。

ポイントはタイプです。それ自体で完全に定義されているすべての構造体、クラス、またはプロトコルは純粋な型です。 ただし、プロトコルまたは構造体が T などの別のジェネリック型プレースホルダーに依存する場合、これは部分型です。

タイプは、コンパイラが特定のメモリを割り当てる必要があるデータ構造です。

だから、このようなもの:

let a = Array<T>()またはlet b = T、コンパイラがコンパイル時に推測するのに十分な情報ではありません。

したがって、これは機能しません。

  extension IntegerType {

    func squared () -> IntegerType { // this line creates error

        return self * self

    }
}

ここで、IntegerType は部分型です。これは、準拠した場合にのみ正確なタイプを知ることができる汎用プロトコルです。アレイに似ています。配列自体は型ではありません。汎用コンテナです。誰かが Array() または Array()... で作成した場合にのみ、型があります。

同じことがあなたにも起こりました。

public protocol IntegerType : _IntegerType, RandomAccessIndexType {

また、

public protocol RandomAccessIndexType : BidirectionalIndexType, Strideable, _RandomAccessAmbiguity {
@warn_unused_result
    public func advancedBy(n: Self.Distance) -> Self

また、

   public protocol _RandomAccessAmbiguity {
    associatedtype Distance : _SignedIntegerType = Int
   }

したがって、RandomAccessIndexType は、誰かがそれに準拠するまで、または準拠しない限り、Self 要件の意味を持つため、Self は未知のプレースホルダーです。パーシャルタイプです。

IntegerType は RandomAccessIndexType および _RandomAccessAmbuiguity に準拠しているため、距離関連型も必要です。

したがって、これもできません

let a: IntegerType = 12

ここでも、IntegerType は Self と Distance (associatedType) を知る必要があります。

ただし、Intはそのような詳細を提供します

public struct Int : SignedIntegerType, Comparable, Equatable {
    /// A type that can represent the number of steps between pairs of
    /// values.
    public typealias Distance = Int

したがって、あなたはそのようなことができます

let a:Int = 10

これは、SignedIntegerType に Self を提供し、他の対応するものに Distance を提供するためです。

簡単に言えば:

具象型を使用できる場所で部分型を使用することはできません。部分型は、他のジェネリックとそれらの制約に適しています。

于 2016-09-06T14:19:29.660 に答える