限制 Swift 中类型的扩展?

问题描述 投票:0回答:2

我在 Swift 中有一个特定的类,我想限制扩展的创建。我尝试添加

final
关键字,但它不限制扩展:

final class MyTest {
    func testFunc() {}
}

extension MyTest {
    func testFunc2() {}
}

let test = MyTest()
test.testFunc2()

这可能吗?

swift swift2 swift-extensions
2个回答
3
投票

您无法阻止某人向您的班级添加扩展。就像您无法阻止其他开发人员编写使用您的类的函数一样。

final
修饰符仅防止子类化。其他开发人员始终能够添加扩展。

真的有问题吗?

恕我直言,事实并非如此。

我们来看看这堂课

final class Person {
    private let name: String
    func tellName() -> String { return "I am \(name)" }
    init(name: String) {
        self.name = name
    }
}

现在另一个开发人员可以编写(到另一个源文件中)这个函数

func presentAndTellName(person: Person) {
    print("Hello everybody! \(person.tellName())")
}

这在其他几种不支持扩展的编程语言中是可能的。嗯,这基本上就是有多少种编程语言可以工作,这也是我们拥有访问控制(私有、公共……)的原因之一。

另一个开发人员实际上无法使用我们类的

private
属性/方法(除非它可以访问我们的源文件)。他也无法向
Person
添加属性,因为它是一个标记为
final
的类,因此子类化是禁止的。他只能编写使用它的代码。

我们都同意这个吧?

然而,编写一个接受参数并仅对该参数起作用的函数有时很难看。函数应该是一个方法,参数值应该是实例。

所以我们使用扩展来转换它

func presentAndTellName(person: Person) {
    print("Hello everybody! \(person.tellName())")
}

进入这个

extension Person {
    func presentAndTellName() {
        print("Hello everybody! \(self.tellName())")
    }
}

这只是编写“相同逻辑”并使其在 OOP 语法糖中可用的一种方式。 现在不用写这个了

presentAndTellName(person)

我们可以写这个

person.presentAndTellName()

将您的资料设为私密

那么如何保护一些类(/struct)逻辑和数据免受扩展影响呢?使用与保护这些内容免受源文件外部函数影响的相同机制,只需将它们标记为

private

。这样其他开发人员将无法在他们的扩展中使用它们。


让我们再看看我们的 Person 类。

class Person { private let name: String func tellName() -> String { return "I am \(name)" } init(name: String) { self.name = name } }

name

属性是市场私有的,因此

没有办法
,外部函数或扩展将能够直接访问它。 等等,协议怎么样?

好吧,这可能是扩展提供的不仅仅是更好的语法的唯一东西。

事实上给出了这个协议

protocol Runner { func run() }

我们可以将其归为我们不拥有的类

extension Person: Runner { func run() { print("🏃") } }



0
投票

class MyClass { private var privateVariable = "Hello, private!" } extension MyClass { func accessPrivateVariable() -> String? { return withUnsafePointer(to: &privateVariable) { $0.withMemoryRebound(to: String.self, capacity: 1) { $0.pointee } } } } let myObject = MyClass() if let value = myObject.accessPrivateVariable() { print(value) }

© www.soinside.com 2019 - 2024. All rights reserved.