带通用闭包参数的Swift函数

时间:2018-07-31 09:09:17

标签: swift

我有父母和孩子班级

class Animal {
   func write(_ block: ((_ animal: Animal) -> Void) ) throws {
      block(self)
   }
}

class Dog: Animal {
   var name: ""
}

我需要使用 write 函数更改名称。现在我这样做:

let dog = Dog()
dog.write { ($0 as! Dog).name = "Bob" }

但是我想这样做(不对Dog进行修改):

dog.write { $0.name = "Bob" }

该怎么做?

2 个答案:

答案 0 :(得分:0)

为什么还不覆盖write类中的Dog函数?像下面这样的事情。

class Animal {
    func write(_ block: ((_ animal: Animal) -> Void) ) throws {
        block(self)
    }
}

class Dog: Animal {
    var name =  ""

    override func write(_ block: ((Dog) -> Void)) throws {
        block(self)
    }
}

let myDog = Dog()
try?myDog.write{  $0.name = "Bob" }

答案 1 :(得分:0)

基本上,您需要block参数依赖于调用该方法的对象的类。一种实现此目的的方法是使用Self的协议:

protocol Writable { }

extension Writable {
    // Self can be used in protocols, and point to the concrete implementation
    // of the protocol
    func write(_ block: ((Self) -> Void) ) throws {
        block(self)
    }
}

// Just need to declare the conformance, all subclasses will inherit it
class Animal: Writable { }

class Dog: Animal {
    var name = "Unnamed"
}

let dog = Dog()
print("Dog name:", dog.name)
try dog.write { $0.name = "Bob" }
print("Dog name:", dog.name)

如预期的那样,上面的代码将打印

Dog name: Unnamed
Dog name: Bob

请注意,write不是协议要求的一部分,您可以将其添加到协议方法列表中,但是使用Self作为协议要求的一部分将限制协议可以使用的位置。 (集合,非泛型函数参数等)被使用。