-1

我有一个协议扩展,它声明并分配一个静态计算变量:

protocol DataType {
    
}
extension DataType {
    static var mocks: [Self] { [] }
}

然后我有另一个名为 Providerassociatedtype的协议,它需要 DataType 协议和扩展:

protocol Provider {
    associatedtype Data: DataType
}

extension Provider {
    static var mock: [Data] {
        Data.mocks
    }
}

然后我创建以下符合 DataType 和 Provider 的类型:

struct Car: DataType {
    var name: String
    
    static var mocks: [Car] {
        [.init(name: "Nissan"), .init(name: "Toyota")]
    }
}

struct CarProvider: Provider {
    typealias Data = Car
}

print(CarProvider.mock)

当我打印出这个(一个空数组[])时,CarProvider静态变量mock会打印出mocksDataType 变量的默认值——即使在其结构定义Car中有一个分配的数组值mocks

但是,只要我将协议mocks内的属性声明DataType为要求,就会正确读取 的mocksCar(打印正确的值:)[__lldb_expr_93.Car(name: "Nissan"), __lldb_expr_93.Car(name: "Toyota")]

protocol DataType {
    static var mocks: [Self] { get }
}

为什么协议定义中首先需要属性定义?扩展值不应该足够吗?而且由于Car结构将自己的值分配给mocks变量,不应该读取它而不是默认扩展值吗?

4

1 回答 1

2

为什么协议定义中首先需要属性定义?扩展值不应该足够吗?

不可以。协议扩展中的实现只能被视为真正的默认实现,如果有某种方式可以在范围内覆盖它。如果没有协议中的要求,Swift 没有理由或机制去超越扩展,因为在语义上没有其他东西可以匹配。

protocol DataType { }

extension DataType {
  static var mocks: [Self] { [] }
}

func mocks<Data: DataType>(_: Data.Type) -> [Data] {
  Data.mocks // This *is* the extension. That is the only truth.
}
protocol DataType {
  static var mocks: [Self] { get }
}

extension DataType {
  static var mocks: [Self] { [] }
}

func mocks<Data: DataType>(_: Data.Type) -> [Data] {
  Data.mocks // Now, we can dispatch to a concrete `Data` type!
}

于 2020-09-29T22:14:02.070 回答