Swift-指一个类';他在班里打字

Swift-指一个类';他在班里打字,swift,Swift,在类型的实例方法中使用静态、类型属性和方法时,我经常重复类型的名称 e、 g 这些对“Foo”的重复引用可能(而且经常)导致复制粘贴、重构时出现错误。很容易忘记更改“Foo”,代码仍然可以编译 所以,我一直在使用这样的模式: class Foo { fileprivate typealias _ThisClass = Foo // Type properties, methods static let kBrandColor = UIColor.red sta

在类型的实例方法中使用静态、类型属性和方法时,我经常重复类型的名称

e、 g

这些对“Foo”的重复引用可能(而且经常)导致复制粘贴、重构时出现错误。很容易忘记更改“Foo”,代码仍然可以编译

所以,我一直在使用这样的模式:

class Foo
{
    fileprivate typealias _ThisClass = Foo

    // Type properties, methods

    static let kBrandColor = UIColor.red
    static let kMeaning = 42

    static func makeThing() -> Thing { ... }

    // Instance method

    func printStuff()
    {
        print("Brand Color is: \(_ThisClass.kBrandColor)")
        print("The meaning of life is: \(_ThisClass.kMeaning)")

        let thing = _ThisClass.makeThing()
        print("Thing is \(thing)"
    }

    ...
}
这种方法有一些复制和粘贴安全性的优点,但要以牺牲一些样板文件为代价


有没有更好、更干净的解决方案?(我已经尝试过这样搜索,但是要找到适合这种问题的搜索词是很棘手的。)

协议在这里很有效。您可以定义协议所需的属性,然后将其应用于要在中使用这些属性的任何类

protocol Brandable {
    var kBrandColor: UIColor { get }
    var kMeaning: Int { get }
}

class Foo: Brandable {
    let kBrandColor: UIColor = .red
    let kMeaning: Int = 42
}
如果要重用printStuff函数,还可以将其放入协议中,并将基本实现放入扩展中:

protocol Brandable {
    var kBrandColor: UIColor { get }
    var kMeaning: Int { get }

    func printStuff()
}

extension Brandable {
    func printStuff() {
        print("Brand Color is: \(kBrandColor)")
        print("The meaning of life is: \(kMeaning)")
    }
}

class Foo: Brandable {
    let kBrandColor: UIColor = .red
    let kMeaning: Int = 42
}

class Bar: Brandable {
    let kBrandColor: UIColor = .blue
    let kMeaning: Int = 100
}

Foo().printStuff()
Bar().printStuff()

makeStuff()函数也可以这样做。共享功能包含在协议及其扩展中。如果需要更改某些类中的行为,只需添加自己的printStuff或MakeSuff函数即可覆盖协议的默认实现。

创建一个类似于
可识别的
的协议,并使用
标识符
属性。然后使您想要的任何类都符合它。这是一种面向协议的方法

protocol Identifiable {
    static var identifier: String { get }
}
extension Identifiable {
    static var identifier: String {
        return String(describing: self)
    }
}

class X: Identifiable {}

您也不需要引用类名。只需调用
类型(of:instance).identifier

[编辑]@Alexander。太棒了。我很高兴这个建议被接受了。OTOH,这项提案两年前就被接受了。。。谢谢谢谢你,尼玛。这是一个有趣的想法。它并没有解决我的总体清洁度和可读性问题,但它确实给了我一些如何更好地构造一些代码的想法。
protocol Identifiable {
    static var identifier: String { get }
}
extension Identifiable {
    static var identifier: String {
        return String(describing: self)
    }
}

class X: Identifiable {}