Swift语言中包含自定义对象的泛型类型

时间:2014-06-03 15:27:28

标签: generics swift

我想知道有没有办法在下面的泛型函数中将两个泛型类型实例与==运算符进行比较:

 func compare<T>(T a, T b) -> Bool {
    if a == b{
       // do something
       return true; 
    }else{
       // do another thing
       return false;
    }   
 }

这是我的自定义对象:

class MyObj{
  var id = 3
  var name: String?
}

3 个答案:

答案 0 :(得分:10)

来自Apple Developer Resources,

  

并非Swift中的每个类型都可以与等于运算符(==)进行比较。例如,如果您创建自己的类或结构来表示复杂的数据模型,则该类或结构的“等于”的含义不是Swift可以为您猜测的。因此,无法保证此代码适用于每种可能的类型T,并且在您尝试编译代码时会报告相应的错误。

     然而,一切都不会丢失。 Swift标准库定义了一个名为
的协议       Equatable,需要任何符合类型才能实现等于运算符(==)       并且不等于运算符(!=)来比较该类型的任何两个值。所有的       Swift的标准类型自动支持Equatable协议。

     

任何Equatable类型都可以安全地与findIndex函数一起使用,因为它保证支持等于运算符。为了表达这一事实,在定义函数时,将Equatable的类型约束写为类型参数定义的一部分:

func findIndex<T: Equatable>(array: T[], valueToFind: T) -> Int? {
    for (index, value) in enumerate(array) {
        if value == valueToFind {
            return index
        }
    }
    return nil
}

以下是他们的文档中的示例,说明如何覆盖==

struct MyStruct: Equatable {
    var name = "Untitled"
}
func == (lhs: MyStruct, rhs: MyStruct) -> Bool {
    return lhs.name == rhs.name
}

let value1 = MyStruct()
var value2 = MyStruct()
let firstCheck = value1 == value2
// firstCheck is true

value2.name = "A New Name"
let secondCheck = value1 == value2
// secondCheck is false

在你的情况下,你会这样做,

class MyObj{
  var id = 3
  var name: String?
}

func == (lhs: MyObj, rhs: MyObj) -> Bool {
    return lhs.id == rhs.id
}

答案 1 :(得分:2)

您可以创建自己的等价运算符 ==和!=的实现,如下所示:

@infix func == (left: MyObj, right: MyObj) -> Bool {
    return (left.id == right.id) && (left.name == right.name)
}
@infix func != (left: MyObj, right: MyObj) -> Bool {
    return !(left == right)
}

var obj1 = MyObj()
var obj2 = MyObj()
obj1.id = 5
obj1 == obj2 // false
obj2.id = 5
obj1 == obj2 // true

obj1.name = "John"
obj1 == obj2 // false

答案 2 :(得分:1)

要使用通用compare()方法,您需要使该类符合Equatable protocol,然后您可以使用==运算符(但您可以轻松调用直接==运算符):

import Cocoa

class MyObj : Equatable {
    var id: Int = 0
    var name: String?
}

func == (lhs: MyObj, rhs: MyObj) -> Bool {
    return lhs.id == rhs.id && lhs.name? == rhs.name?
}


func compare<T: Equatable>(a: T, b: T) -> Bool {
    return a == b
}

var obj1 = MyObj()
obj1.id = 12;
obj1.name = "Andy"
var obj2 = MyObj()
obj2.id = 12;
obj2.name = "Andy"

if compare(obj1, obj2) {
    println("equal")
} else {
    println("not equal")
}