Swift Generics - 如果它们是Equatable则返回等于或返回nil

时间:2017-05-09 04:24:32

标签: swift generics

有没有办法检查泛型类型是否符合Equatable?我希望能够检查相同泛型类型的两个对象是否相等,或者相等对它们没有意义。

由于Equatable只能用作通用约束(因为它有Self或associatedType要求),我尝试过使用泛型重载:

//If T is equatable, this is more specific so should be called
func equals<T:Equatable>(lhs:T, rhs:T) -> Bool?{
    return lhs == rhs
}

//This should only be called if T is not equatable at compile time
func equals<T>(lhs:T, rhs:T) -> Bool?{
    return nil
}

这在使用特定类型调用时有效,例如: equals(lhs:1, rhs:1)按预期返回true。但是,如果在通用上下文中调用它,它总是返回nil

func doSomethingThenCheckEquals<T>(lhs:T, rhs:T){
    //Do something here which has no type requirements

    //Check if the two objects are equal - would usually do something with the result
    //This will always use equals<T> and never equals<T:Equatable>, so will always be nil
    _ = equals(lhs:lhs, rhs:rhs) 
}

有没有办法达到预期的效果?

此外,根据this answer,编译器以带有动态类型检查的单个实现开始,但在某些情况下可以创建专门的实现。在编译器创建专用实现的情况下,它的行为是否与第一种情况类似(equals(lhs:1, rhs:1)返回true)?

1 个答案:

答案 0 :(得分:0)

编译器按预期执行其工作。您声明的第二个方法与第一个方法无关,因此它对T一无所知。

Generic是前向声明,这意味着我们需要告诉编译器它将遵循什么协议,然后编译器将采取所有必要的步骤来适应它。也许将来,我们可以期待函数调用级别类型解释但是目前,它不可用。

func doSomethingThenCheckEquals<T>(lhs:T, rhs:T){
//Do something here which has no type requirements

   //Check if the two objects are equal - would usually do something with the result
   //This will always use equals<T> and never equals<T:Equatable>, so will always be nil
    _ = equals(lhs:lhs, rhs:rhs) 
}

最好的解决方案是使用where子句。

 func doSomethingThenCheckEqual<T>(lhs: T, rhs: T) where T:Equatable {


 }

详细了解here