【问题标题】:Initializing type of `self`初始化`self`的类型
【发布时间】:2017-01-16 03:07:17
【问题描述】:

这行得通

class Die {
    let faces: Int

    required init(faces: Int) {
        self.faces = faces
    }

    func yahtzeeDice() -> [Die] {
        return [Die](repeating: type(of: self).init(faces: 6), count: 5)
    }
}

这似乎违反了 DRY。可以在yahtzeeDice函数中间接引用Die吗?

【问题讨论】:

  • 你说的是yahtzeeDice()的方法签名中的[Die]还是body?后者可以替换为Array,因为可以推断出Die的元素类型。
  • 无关:为什么yahtzeeDice()是一个实例方法?您可以将其设为 static/class 方法,然后使用 self 而不是 type(of: self)
  • 你不能在签名中使用[Self],因为数组是一个结构,如果A : B那么[A][B]仍然是不相关的类型。
  • 还要注意,上面[Die]数组的重复初始化器用实例化一个 Die实例,此后重复引用这个实例5在数组(因为Die 是引用类型)。即,[Die] 的所有成员都持有对同一底层 Die 实例的强引用。
  • 间接引用它的目的是什么,即您要解决什么问题?您是否打算经常更改课程名称?

标签: swift


【解决方案1】:

首先,请注意您问题中[Die] 数组的重复初始化程序将实例化单个 Die 实例,然后在数组中重复对该实例的引用 5 次(因为Die 是引用类型)。即,您的示例中 [Die] 的所有成员都对相同的底层 Die 实例具有强引用。因此,如果您使用引用类型,请记住避免重复的数组初始值设定项。


现在,您可以构建一个协议,该协议提供蓝图 static dice 供应商方法的默认实现,该方法提供 Self 实例数组,使用其他一些蓝图初始化程序。

// the 'class' requirement not strictly needed here, but it holds semantic
// value to explain the 'map' call rather than using array:s 'repeating' 
// initializer in in the default implementation below
protocol DiceFactory: class {
    init(faces: Int, id: Int)
    static func dice(_ n: Int) -> [Self]
}
extension DiceFactory {
    static func dice(_ n: Int) -> [Self] {
        return (1...n).map { Self.init(faces: 6, id: $0) }
    }
}

如果您将Dice 类标记为final(为什么是final?请参阅下面链接的问答),则在符合DiceFactory 协议时,您将可以直接访问此默认实现。

final class Die: DiceFactory {
    let id: Int
    let faces: Int

    init(faces: Int, id: Int) {
        self.faces = faces
        self.id = id
    }
}

let myDice = Die.dice(5)
myDice.forEach { print($0, $0.id) }
    /* Die 1
       Die 2
       Die 3
       Die 4
       Die 5 */

但话说回来,你有充分的理由不明确输入Die吗?

另见:

【讨论】:

  • 一个小改进,可以使用(1...n).map { Self.init(...) }来生成数组。
  • 请注意,Array(repeating:count:) 可能的使用是有意的,因为 Die 实例是不可变的(有可能 OP 只是使用一个类进行继承——如果这是不是这样,那么它肯定应该是struct)。
猜你喜欢
  • 2020-09-14
  • 2020-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-31
  • 2013-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多