无法在Swift中的Array扩展方法中创建默认闭包参数

作为学习
Swift的练习,我尝试使用名为comparest的共享方法在Array上创建最小和最大扩展方法.一切都经过测试,效果很好,除了一件事:没有参数,我不能使用最小函数.我已经指定了一个默认参数值nil,但是当我在没有这个参数的情况下调用minimum时,Apple的Swift编译器不喜欢它.

这是我的方法定义.他们编译得很好.

extension Array {

  func comparest<C: Comparable>(comparator: T -> C, _ op: (C, C) -> Bool) -> T? {
     var min = self.first
     for elem in self {
         if op(comparator(elem), comparator(min!)) {
            min = elem
         }
     }
     return min
  }                     

  func minimum<C: Comparable>(var _ comparator: (T -> C)? = nil) -> T? {
     if comparator == nil {
         comparator = { elem -> C in elem as C }
     }
     return self.comparest(comparator!, { $0 < $1 }) 
  }

}

(如果你想知道为什么我说比较(比较器!,{$0< $1})而不是比较(比较器!,<),请参阅我的related question.)

如果我说

var array = [3, 4, 1, 9]
var min = array.minimum({ $0 })

一切顺利.但是,我设计了这个方法,以便可以省略传递给minimum的参数,在这种情况下,数组元素本身被用作比较值,例如,

var array = [3, 4, 1, 9]
var min = array.minimum()

编译器讨厌这个.它说“无法将表达式的类型()转换为Int?”.我在这里很无能为力.有什么想法吗?

(暂时不说,参数的原因是你想比较一个属性的值,比如,对象,例如routes.map({$0 as MKRoute}).minimum({$0.distance})将给你最小距离的路线.)

最佳答案 数组中的元素不必是Comparable,这意味着您无法为所有可能的数组编写该函数.

不幸的是,Swift不允许你只扩展数组的子集.在其他功能中,编译器需要额外的类型信息来推断类型C.

其他人也在努力解决同样的问题:

How can we create a generic Array Extension that sums Number types in Swift?

您应该能够使用minimum作为全局函数,而不是使用扩展.

点赞