比较可选数组

Ste*_*ntz 19 swift

在操场上运行以下代码段会出错:

let a: [Int]? = [1,2]
let b: [Int]? = [1,2]
a == b // value of optional type '[Int]?' not unwrapped; did you mean to use '!' or '?'?
Run Code Online (Sandbox Code Playgroud)

虽然为"更简单"的可选类型做类似的工作:

var x: Int? = 10
var y: Int?
x == y // false
Run Code Online (Sandbox Code Playgroud)

第一种情况,可选数组背后的原因是什么,不被允许?为什么Swift首先不能看到if nil(.None)然后如果它们不是,那么就进行实际的数组比较.

Air*_*ity 31

它适用于更简单类型的原因是因为有一个版本==是为包含以下类型的选项定义的Equatable:

func ==<T : Equatable>(lhs: T?, rhs: T?) -> Bool
Run Code Online (Sandbox Code Playgroud)

但是,虽然IntEquatable,但Array不是(因为它可能包含一些不相同的东西 - 在这种情况下它怎么可能).所有Equatable东西都有一个==操作员,但不是所有东西都有==操作员Equatable.

您可以编写一个专门==用于包含equatable类型的可选数组的特例版本:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool {
    switch (lhs,rhs) {
    case (.Some(let lhs), .Some(let rhs)):
        return lhs == rhs
    case (.None, .None):
        return true
    default:
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

您还可以将其概括为涵盖包含equatable元素的任何集合:

func ==<C: CollectionType where C.Generator.Element: Equatable>
  (lhs: C?, rhs: C?) -> Bool {
    switch (lhs,rhs) {
    case (.Some(let lhs), .Some(let rhs)):
        return lhs == rhs
    case (.None, .None):
        return true
    default:
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 苹果公司没有直接实施的原因是否有任何理由? (3认同)

Vic*_*hou 8

添加swift 3版Airspeed的答案:

func ==<T: Equatable>(lhs: [T]?, rhs: [T]?) -> Bool {
  switch (lhs,rhs) {
  case (.some(let lhs), .some(let rhs)):
    return lhs == rhs
  case (.none, .none):
    return true
  default:
    return false
  }
}

func ==<C: Collection where C.Iterator.Element: Equatable>(lhs: C?, rhs: C?) -> Bool {
  switch (lhs,rhs) {
  case (.some(let lhs), .some(let rhs)):
    return lhs == rhs
  case (.none, .none):
    return true
  default:
    return false
  }
}
Run Code Online (Sandbox Code Playgroud)