Swift协议中类继承协议的mutating问题

之前实际开发的时候遇到的一个小问题,网上也没有找到相关说明。本来当时弄明白了想着记下来的,但是比较忙就耽搁了,趁今天休息记录一下。

首先,我们看一下下面这个两数之和的协议

protocol Test: CustomStringConvertible {

    var num1: Int { get set }

    var num2: Int { get set }

    func getSum() -> Int

    func sum() //num1 变为num1+num2

}

 

extension Test {//文字输出num1

     var description: String {

        return "\(num1)"

    }

}

 

extension Test {

    func getSum() -> Int {

        return num1 + num2

    }

    mutating func sum() { //改变自身的变量,要加mutating

        num1 += num2

    }

 

}

 

playground没有报错,说明这个协议没问题。但是我们来试一下让class继承这个看似没有问题的协议

class TestClass: Test {

    var num1: Int

    var num2: Int

    init() {

        num1 = 0; num2 = 0

    }

    convenience init(_ num1: Int, _ num2: Int) {

        self.init()

        self.num1 = num1; self.num2 = num2

    }

 

}

结果编译器报错,Type 'TestClass' does not conform to protocol 'Test'

到底哪里出问题了?仔细一想,对于类而言mutating是不需要的,这是枚举型和结构体里改变自身变量的方法才需要前置的关键词。

最后个人的解决方案就是声明这个协议只有类可以继承,这样就可以删掉mutating了

protocol Test: class, CustomStringConvertible {

    var num1: Int { get set }

    var num2: Int { get set }

    func getSum() -> Int

    func sum() //num1 变为num1+num2

}

 

extension Test {//文字输出num1

     var description: String {

        return "\(num1)"

    }

}

 

extension Test {

    func getSum() -> Int {

        return num1 + num2

    }

    func sum() { //改变自身的变量,要加mutating

        self.num1 += self.num2

    }

}

 

class TestClass: Test {

    var num1: Int

    var num2: Int

    init() {

        num1 = 0; num2 = 0

    }

    convenience init(_ num1: Int, _ num2: Int) {

        self.init()

        self.num1 = num1; self.num2 = num2

    }

 

}

 

然后测试一下

var test = TestClass(1, 2)

print(test)

test.sum()

 

print(test)

 

运行结果如下

1

 

3

 

posted @ 2017-04-02 17:13  懒虫哥哥  阅读(710)  评论(0编辑  收藏  举报