Swift中的协议

Swift中的协议

Swift中的常用协议

Equatable

Equatable 协议用于相等的比较,遵守这个协议后必须对==运算符进行重载。

struct Record: Equatable {
    var wins: Int
    var losses: Int
}

func ==(left: Record, right: Record) -> Bool {
    return left.wins == right.wins && left.losses == right.losses
}

let recordA = Record(wins: 10, losses: 5)
let recordB = Record(wins: 10, losses: 5)

recordA == recordB//true
recordA != recordB//false

重载==之后,!=也可以正常使用

Comparable

Comparable协议用于比较,只需要重载<就可以了

struct Record: Equatable, Comparable {
    var wins: Int
    var losses: Int
}

func ==(left: Record, right: Record) -> Bool {
    return left.wins == right.wins && left.losses == right.losses
}

func <(left: Record, right: Record) -> Bool {
    if left.wins != right.wins {
        return left.wins < right.wins
    }
    return left.losses > right.losses
}

Record遵守Comparable协议,表示其是一个可比较的对象。

var team1Record = Record(wins: 10, losses: 3)
var team2Record = Record(wins: 8, losses: 5)
var team3Record = Record(wins: 8, losses: 8)
var records = [team1Record, team2Record, team3Record]

records.sort()

CustomStringConvertible

遵循CustomStringConvertible协议,只需要实现一个计算型的属性description

struct Record: Equatable, Comparable, CustomStringConvertible {
    var wins: Int
    var losses: Int

    var description: String {
        return "WINS: " + String(wins) + " , LOSSES: " + String(losses)
    }
}

这时print(team1Record) 输出的结果就为:WINS: 10 , LOSSES: 3

BooleanType

BooleanType可以让一个类型被视为一个布尔值,需要覆盖一个boolValue属性。

var boolValue: Bool {
    return wins > losses
}

就可以这样使用if语句:

if recordA {

}

同样可以让基本类型实现BooleanType协议,这样就可以直接来进行布尔判断,如下:

extension Int: BooleanType {
    public var boolValue: Bool {
        return self != 0
    }
}

var wins = 0
if !wins {
    print("You never win!")
}

面向协议编程

运算符重载

内容来自Operator Overloading in Swift Tutorial

例如,重载+运算符,使两个Int型数组相加:

func +(left: [Int], right: [Int]) -> [Int] { // 1
    var sum = [Int]() // 2
    assert(left.count == right.count, "vector of same length only")  // 3
    for (key, v) in enumerate(left) {
      sum.append(left[key] + right[key]) // 4
    }
    return sum
}

自定义运算符
定义一个自定义运算符有三步:

  • Name your operator命名运算符
    自定义的运算符可以是ASCII字符,如/, =, -, +, !, *, %, <, >, &, |, ^,也可以是Unicode字符。
  • Choose a type选择一个类型
    在Swift中,可以定义binary, unaryternary运算符,即一元、二元、三目运算符。
  • Assign precedence and associativity指定优先级和结合型

关键字:

  • operator
  • prefix 前缀运算符,比如 (取正+、取负- 、自增++、自减–)
  • postfix 后缀运算符,比如(自增++、自减–),这两可以前缀也可以后缀
  • infix 中缀,最常见二元运算
  • precedence 优先级的意思,取值 0~255 ,纯数字,不可以带符号,下划线,指数e/p 表示
  • associativity 结合性,可以是 left, right, 或者 none

如下,自定义运算符,使两个Int类型数组相加:

infix operator ⊕ { associativity left precedence 140 } // 1
func ⊕(left: [Int], right: [Int]) -> [Int] { // 2
    var sum = [Int](count: left.count, repeatedValue: 0)
    assert(left.count == right.count, "vector of same length only")
    for (key, v) in enumerate(left) {
        sum[key] = left[key] + right[key]
    }
    return sum
}

泛型运算符
如下,指定类型:

infix operator ⊕ { associativity left precedence 140 }
func ⊕<T>(left: [T], right: [T]) -> [T] { // 1
    var minus = [T]()
    assert(left.count == right.count, "vector of same length only")
    for (key, v) in enumerate(left) {
        minus.append(left[key] + right[key]) // 2
    }
    return minus
}

但是,会报错Could not find an overload for '+' that accepts the supplied arguments.。由于不知道类型,Swift不知道怎样相加。

所以,一般的做法是,先定义一个协议,再扩展原有类型:

protocol Number {  // 1
    func +(l: Self, r: Self) -> Self // 2
}

extension Double : Number {} // 3
extension Float  : Number {}
extension Int    : Number {}

infix operator ⊕ { associativity left precedence 140 }
func ⊕<T: Number>(left: [T], right: [T]) -> [T] { // 4
    var minus = [T]()
    assert(left.count == right.count, "vector of same length only")
    for (key, v) in enumerate(left) {
        minus.append(left[key] + right[key])
    }
    return minus
}

参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Swift ,可以使用协议来限制属性的特定实现。下面是一些示例: 1. 只读属性协议 我们可以定义一个只读属性协议,让遵循该协议的类型只能实现只读属性: ``` protocol ReadOnlyProperty { var value: Int { get } } struct MyStruct: ReadOnlyProperty { let value: Int } ``` 在上面的代码,`ReadOnlyProperty` 协议定义了一个只读属性 `value`。然后,我们定义了一个结构体 `MyStruct`,该结构体遵循 `ReadOnlyProperty` 协议,并实现了只读属性 `value`。 2. 可写属性协议 我们可以定义一个可写属性协议,让遵循该协议的类型只能实现可写属性: ``` protocol WritableProperty { var value: Int { get set } } struct MyStruct: WritableProperty { var value: Int } ``` 在上面的代码,`WritableProperty` 协议定义了一个可读写属性 `value`。然后,我们定义了一个结构体 `MyStruct`,该结构体遵循 `WritableProperty` 协议,并实现了可写属性 `value`。 3. 只写属性协议 我们可以定义一个只写属性协议,让遵循该协议的类型只能实现只写属性: ``` protocol WriteOnlyProperty { var value: Int { set } } class MyClass: WriteOnlyProperty { var value: Int = 0 } ``` 在上面的代码,`WriteOnlyProperty` 协议定义了一个只写属性 `value`。然后,我们定义了一个类 `MyClass`,该类遵循 `WriteOnlyProperty` 协议,并实现了只写属性 `value`。 通过以上示例,我们可以看到如何使用协议来限制属性的特定实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值