我有一个通用结构。我在扩展中的结构中添加了一个方法,如下所示-
struct CustomStruct<T> {
let data: T?
}
extension CustomStruct {
func method1() {
}
}
当T
的类型为String
时,我希望method1
执行不同的操作。
我尝试添加另一个具有通用类型约束的扩展,如下所示-
extension CustomStruct where T == String {
func method1() {
print("method1 for string called")
}
}
但是,当执行以下代码时,不会调用上述方法。
let struct1 = CustomStruct<String>(data: "something")
struct1.method1()
谁能指出解决这个问题的方法?
编辑-上面的代码没有指出@scriptable和@matt指出的问题。以下代码指出了我遇到的问题
struct CustomStruct<T> {
let data: T?
}
extension CustomStruct {
func method1() {
print("method1 for all type called")
}
}
extension CustomStruct where T == String {
func method1() {
print("method1 for string called")
}
}
func callMethod1<T>(customStruct: CustomStruct<T>) {
customStruct.method1()
}
let struct1 = CustomStruct<String>(data: "something")
callMethod1(customStruct: struct1)
答案 0 :(得分:2)
无法从您给出的示例中复制问题。我将假设您遇到了一个更复杂的问题,您试图将其归结为该问题,并且错误地将其归结为错误。我猜想您实际上看到的是这样的:
struct CustomStruct<T> {
let data: T?
func method1() {
print("original method1")
}
func method2() {
method1()
}
}
extension CustomStruct where T == String {
func method1() {
print("method1 for string called")
}
}
let struct1 = CustomStruct(data: "something")
struct1.method1() // method1 for string called
struct1.method2() // original method1
如您所见,如果我们直接调用method1
,我们将通过扩展名。 (这就是为什么不能从您给出的示例中复制问题的原因。)但是,如果我们调用method2
,而调用method1
,则会得到原始的method1
,而不是属于扩展名。
这是真正的问题吗?
如果是这样,则您可能会遇到一个常见的误解,即您试图使用where
子句来启用某种基于类型的分派。这是错误的,不是where
子句的用途。正如Jordan Rose所说的here:
在Swift中,要调用的函数是在调用位置选择的。
获得基于类型的调度的方法(他继续说)是通过诸如覆盖(多态)和重载(不同的方法签名)之类的标准方法。或者,您当然可以自己检查类型并实时做出决定。
换句话说:您不能使用扩展来执行方法重写。但这正是您要尝试做的。您不能使用where子句将结构转换为类(动态调度),也不能执行重载。