假设我创建了一个这样的协议(protocol):
protocol A {
associatedtype T
func computeSomething(with:T) -> Double
}
在我的通用类型类中,我想做这样的事情:
class B<U> {
var doSomething:A<U>
}
这件事是这会产生一个错误,但我想接受任何支持我的类型
U
上的 computeSomething 的类型但我根本不知道该怎么做?为清晰起见进行编辑
基本上,如果 A 是通用结构或类,那将是可能的,但是如果没有默认实现(由类或结构提供)在这里有意义并且我唯一想要的是确保该类型符合我的要求怎么办?
编辑#2(带有具体示例)
我想简化我的问题,这使得它很难理解,所以这里是一个仍然简化和虚构的问题,可能更符合我遇到的问题:
我正在编写一个处理其泛型类型的泛型类
T
:class Process<T> { ... }
类(class)
Process
本身包含处理 T
的代码,但为了使此代码正常工作,它需要 T
符合某些协议(protocol),例如:protocol A {
func mixWith(other:A) -> A
}
protocol B {
var isFoo:Bool { get set }
}
所以我的第一个方法是简单地要求
T
遵守这些协议(protocol):class Process<T:<A,B>> { ... }
这看起来是最简单的方法,可能在很多情况下都是如此,但就我而言,我认为这实际上是有问题的,原因如下:
首先,我可能需要以多种不同的方式处理同一个类型,而改变处理类型的方式通常需要改变协议(protocol)的实际实现
A
和 B
例如在这种情况下,fooProcess
和 barProcess
都是 Process
类型泛型 MyType
:let fooProcess = Process<MyType>()
let barProcess = Process<MyType>()
但我想要
fooProcess
和 barProcess
执行不同的操作,在许多情况下需要更改 A
的实现和 B
我的 MyType
的协议(protocol)类型,这是不可能的。所以我的第一个想法是简单地要求定义一些闭包和变量,这样我就不再需要协议(protocol),并且只在我的
Process
中定义数据处理方式。类,有点像这样:class Process<T> {
//
var mix:(_ lhs:T, _ rhs:T)->(T)
var isFoo:(_ a:T)->(Bool)
...
}
所有的处理都将直接在我的
Processing
中实现。类,这看起来像是正确的解决方案,但现在又出现了另一个问题,这导致我使用关联类型方法:事实证明,在许多情况下,我的 Process
的用户类希望获得一些由我的框架实现的默认行为,例如,我可以自动实现协议(protocol) A
和 B
只要他们的类(class)符合协议(protocol) X
,这是它是如何做到的:protocol X:A,B {
...
}
extension protocol X {
// Here was my default implementation of A and B, which enabled my user to directly get A and B implemented as long as their type conformed to X
}
通过使用这种方法,我可以让我的用户直接选择他们想要实现的内容,符合协议(protocol)
X
他们只需要编写一点代码,让我的框架自行处理所有其余部分,如果他们想实现自己的 A 或 B,他们仍然可以。所以如果我是对的,我的闭包实现就没有办法做这样的事情。
因此,出于这个原因,我认为关联类型协议(protocol)将是一个很好的解决方案,因为在这里我可以让我的用户轻松获得一些默认行为或编写他们自己的行为,所以现在我们回到我最初的问题:
protocol AProcessing {
associatedtype U
func mix(_ lhs:U, _ rhs:U) -> U
}
protocol BProcessing {
associatedtype U
func isFoo(_ a:U) -> Bool
}
然后做这样的事情:
class Process<T> {
var aProcessor:AProcessing<T>
var bProcessor:BProcessing<T>
}
与闭包相比,这里的优点是我可以编写一个符合 AProcessing 的特殊类,它可以提供默认实现,这样:
class AutomaticAProcessing<T:X>:AProcessing { ... }
那将使我的用户能够这样做:
var processData = Process<SomeType>()
processData.aProcessor = AutomaticAProcessing<SomeType>()
processData.bProcessor = TheirOwnImplemtation
这不仅在 Swift 中是不可能的,而且感觉就像我使用了太多的“hacks”来完成事情,应该有一个更简单的语言功能来做到这一点,不幸的是我不知道我应该使用什么。
最佳答案
我认为这是不可能的,因为协议(protocol)的泛型类型是在实现它的类中指定的。
你可以这样写:
class B<U, P: A> where P.T == U {
var someVar: P?
}
但是,您需要为特定类指定第二个参数。例如:
class C: A {
typealias T = String
func computeSomething(with: String) -> Double {
return 0.0
}
}
let b = B<String, C>()
let c = b.someVar
但它不能在其
associatedtype
中返回具有特定类型的协议(protocol)。
关于swift - 我应该如何用 Swift 写这个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42055677/