如何基于泛型类型执行泛型结构的方法的不同实现?

时间:2019-08-16 13:22:21

标签: swift

我有一个通用结构。我在扩展中的结构中添加了一个方法,如下所示-

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)

1 个答案:

答案 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子句将结构转换为类(动态调度),也不能执行重载。

相关问题