【问题标题】:Swift Generics - return equals if they are Equatable, or return nilSwift 泛型 - 如果它们是 Equatable 则返回等于,或者返回 nil
【发布时间】:2017-05-09 04:24:32
【问题描述】:

有没有办法检查泛型类型是否符合 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)?

【问题讨论】:

  • 为什么在调用equals(lhs:1, rhs:1) 时会期待false
  • 啊,好点 - 我不会

标签: swift generics


【解决方案1】:

编译器正在按预期工作。您声明的第二种方法独立于第一种方法,因此它对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

【讨论】:

  • 这不是一个真正的解决方案,因为无论 T 是否符合 Equatable,我都想做一些事情。您的回答将要求我写 func doSomethingThenCheckEquals&lt;T:Equatable&gt;(lhs:T, rhs:T)func doSomethingThenCheckEquals&lt;T&gt;(lhs:T, rhs:T) 做完全相同的事情,除了第二个不检查等于。这是不可接受的,就好像它在另一个通用函数中一样,因为我的“等于”函数不起作用,它也需要重复代码。
猜你喜欢
  • 2021-11-19
  • 1970-01-01
  • 2015-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-21
  • 1970-01-01
相关资源
最近更新 更多