在遵守具有关联类型的协议时,如何快速使用 DI?

问题描述 投票:0回答:1

我想快速实现这样的目标:

protocol P {}
protocol P1: P {}
class P1Impl: P1 {}

protocol PBase {
  associatedtype T: P
  var prop: T { get }
}

struct S: PBase {
  typealias T = P1 // <---- The problem

  // This property is got via DI, so I don't know
  // the actual type of it.
  @Injected var prop: P1
}

现在的问题是这段代码无法编译,原因是行

typealias T = P1
。编译器想要知道实际类型而不是
P1
(虽然我没有该类型)。

如果协议

P
有必需的静态属性,我会理解这个限制。在这种情况下,我们可以在没有任何实例的情况下获取该属性的值,因此确实需要实际类型。然而在我的例子中没有这样的属性。

不管怎样,我喜欢swift,想快速地解决这个任务。对于这种情况,最佳做法是什么?

附注

我认为仿制药可以有所帮助:

struct S<T: P1>: PBase {
  var prop: T
}

但是在这种情况下,我在创建

T
实例时也不知道
S
的类型,因为 DI 返回协议。

swift generics dependency-injection protocols associated-types
1个回答
0
投票

正如其中一条评论中提到的,我确实认为可能值得检查

any P
返回值以及您的
associatedtype
要求是否确实需要。否则你可以尝试使用类型擦除:

struct AnyP1: P1 {
    var actual: any P1

    init(_ actual: any P1) {
        self.actual = actual
    }
}

这将 P1 实现包装为已知类型,该类型也符合

P1
协议。然后在您的
S
对象中,您应该执行以下操作:

struct S: PBase {
    typealias T: AnyP1

    var prop: T
}

// Or shorthand

struct S: PBase {
    var prop: AnyP1
}

您的

S
现在将始终知道
T
的类型,并且类型擦除将包含实际的底层协议值。

© www.soinside.com 2019 - 2024. All rights reserved.