init()如何与Swift协议相关?

时间:2017-03-09 11:33:06

标签: swift protocols

Swift中的协议可以在其定义中声明def modify_broadcast(j,test): main=j[0] context=j[1] test.value[main]=test.value[main]+1 test.value[context]=test.value[context]+1 return test.value test = sc.parallelize([(1),(2),(3),(4)]).zipWithIndex().map(lambda x: (x[1],x[0])) test = sc.broadcast(test.collectAsMap()) print(test.value[0]) coocurence = sc.parallelize([(0,1),(1,2),(3,2)]).map(lambda x: modify_broadcast(x,test)) 方法。但是,我想不出任何用例,除了强制符合类在协议中定义init()之外,它解决了任何问题。我们可以在协议类型上调用声明的方法,但是协议上的init不能用于实例化它的对象,这是它唯一的目的。

协议中声明init()方法解决了什么问题?

3 个答案:

答案 0 :(得分:2)

它强制类从某些数据中获取init(data: data),例如:

protocol JSONable {
    init(data: JSON)
}

强制JSONable的所有类都有来自JSON的初始化者,因此您始终可以确定,您可以从JSON创建实例。

答案 1 :(得分:2)

我认为实用的实用程序在它被用作泛型类函数中的约束时出现。这是我的一个项目的真实代码。

我声明了一个带有init的协议:

protocol JSONCreatable {
    init(fromJson json: JSON)
}

然后,在泛型函数中,我返回一个符合该协议的类:

import SwiftyJSON

extension JSON {
    func asObject<T>() -> T? where T: JSONCreatable {
        if isEmpty {
            return nil
        }
        return T(fromJson: self)
    }

    func asArray<T>() -> [T] where T: JSONCreatable {
        return array?.map{ json in T(fromJson: json) } ?? []
    }
}

这允许我做这样的事情:

let user: User = json["user"].asObject()
let results: [Element] = json["elements"].asArray()

答案 2 :(得分:1)

它通常用于允许协议扩展和受约束的通用占位符调用符合协议的给定具体类型的初始化器。例如,考虑RangeReplaceableCollectioninit<S : Sequence>(_ elements: S)默认实现:

extension RangeReplaceableCollection {

    // ...

    /// Creates a new instance of a collection containing the elements of a
    /// sequence.
    ///
    /// - Parameter elements: The sequence of elements for the new collection.
    public init<S : Sequence>(_ elements: S) where S.Iterator.Element == Iterator.Element {
      self.init()
      append(contentsOf: elements)
    }
    // ...
}

如果没有将init()定义为RangeReplaceableCollection的协议要求,则扩展无法知道我们可以调用init()来创建符合类型的新实例

但它也可以在泛型和扩展之外直接使用 - 例如,它可以用于构造一个由给定的存在元类型表示的新实例(某种具体类型的元类型)符合协议'):

protocol P {
    init()
}
struct S : P {
    init() {}
}

let s: P = S()
let s1 = type(of: s).init() // creates a new instance of S, statically typed as P.

在这个例子中:

  • type(of: s)s的动态类型作为P.Type(存在的元类型)返回,因为s被静态输入为P。请注意,type(of:)(T) -> T.Type操作。

  • init()构建底层具体类型的新实例,在本例中为S

  • 新实例静态输入为P(即在存在容器中装箱)。