为什么泛型函数在具有Comparable约束的泛型函数中丢失?

时间:2014-06-05 22:27:06

标签: swift

当创建一个没有约束的普通泛型函数时,它按预期工作,即:

func select<T,U>(x:T, f:(T) -> U) -> U {
    return f(x)
}

类型流入closure参数,它允许我以强类型访问它,即:

var b1:Bool = select("ABC") { $0.hasPrefix("A") }
var b2:Bool = select(10) { $0 > 0 }

当我添加Equatable约束时,它继续有效:

func selectEquatable<T : Equatable, U : Equatable>(x:T, f:(T) -> U) -> U {
    return f(x)
}

var b3:Bool = selectEquatable("ABC") { $0.hasPrefix("A") }

但由于某种原因,在使用Comparable约束时失败:

func selectComparable<T : Comparable, U : Comparable>(x:T, f:(T) -> U) -> U {
    return f(x)
}

var b4:Bool = selectComparable("ABC") { $0.hasPrefix("A") }

因构建错误而失败:

  

找不到会员'hasPrefix'

但它确实允许在类型流经String

的情况下返回
var b5:String = selectComparable("ABC") { $0 }

查看API文档显示String为Comparable

extension String : Comparable {
}

它甚至允许从String隐式转换为Comparable

var str:Comparable = ""

那么为什么我不能将它作为一个强类型字符串在我的Closure中访问?

var b4:Bool = selectComparable("ABC") { $0.hasPrefix("A") } //build error

2 个答案:

答案 0 :(得分:1)

这不是String。您的约束{ $0.hasPrefix("A") }的返回类型为Bool,已分配给UBoolEquatable,但不是Comparable

您可能希望闭包返回Bool,但selectComparable返回U

修改

以下证据表明,返回StringComparable)而不是Bool(不是Comparable)将会编译:

func selectComparable<T: Comparable, U: Comparable>(x:T, f:(T) -> U) -> U {
    return f(x)
}
var b4 = selectComparable("ABC") { (str: String) -> String in str }

答案 1 :(得分:1)

您的selectComparable声明不正确。

func selectComparable<T: Comparable, U: Comparable>(x:T, f:(T) -> U) -> U {
    return f(x)
}

U:Comparable不适用于Bool类型,它不是Comparable,只有Equatable

这样可以正常使用

func selectComparable<T: Comparable, U>(x:T, f:(T) -> U) -> U {
    return f(x)
}

func select<T:Comparable,U: Equatable>(x:T, f:(T) -> U) -> U {
    return f(x)
}