在 Swift 中限制类型的扩展名?
Restrict extensions on a type in Swift?
我在 Swift 中有一个特定的 class,我想限制创建扩展。我尝试添加 final
关键字,但它不限制扩展名:
final class MyTest {
func testFunc() {}
}
extension MyTest {
func testFunc2() {}
}
let test = MyTest()
test.testFunc2()
这可能吗?
您无法阻止他人向您的 class 添加扩展。就像您无法阻止其他开发人员编写使用您的 class.
的函数一样
The final
modifier only prevents subclassing. Other developers will always be able to add extensions.
真的有问题吗?
恕我直言,它不是。
我们来看看这个class
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())")
}
这在其他几种不支持扩展的编程语言中是可能的。好吧,这基本上是有多少种编程语言可以工作,这也是我们拥有访问控制的原因之一(私有,public,...)。
另一个开发者实际上不能使用我们的 class 的 private
properties/methods(除非它可以访问我们的源文件)。他也不能向 Person
添加属性,因为它是一个标记为 final
的 class,所以 subclassing 是禁止的。他只能编写使用它的代码。
我们都可以接受吗?
然而,编写一个接受参数并仅处理该参数的函数有时很丑陋。函数应该是方法,参数值应该是实例。
所以我们使用扩展来转换这个
func presentAndTellName(person: Person) {
print("Hello everybody! \(person.tellName())")
}
进入这个
extension Person {
func presentAndTellName() {
print("Hello everybody! \(self.tellName())")
}
}
这只是一种编写相同逻辑并使其在 OOP 语法糖中可用的方法。
现在不用写这个
presentAndTellName(person)
我们可以这样写
person.presentAndTellName()
将您的资料设为私有
那么如何保护您的一些 class (/struct) 逻辑和数据不受扩展的影响?使用您用来保护这些东西免受源文件外部函数影响的相同机制,只需将它们标记为 private
。这样其他开发人员将无法将它们用于他们的扩展。
让我们再看看我们的人物 class。
class Person {
private let name: String
func tellName() -> String { return "I am \(name)" }
init(name: String) {
self.name = name
}
}
name
属性 是私有市场,因此 没有办法 并且外部函数或扩展程序将能够直接访问它。
等等,协议呢?
好的,这可能是扩展提供的不仅仅是更好语法的唯一东西。
事实上给定这个协议
protocol Runner {
func run()
}
我们可以符合它 class 我们不拥有
extension Person: Runner {
func run() { print("") }
}
我在 Swift 中有一个特定的 class,我想限制创建扩展。我尝试添加 final
关键字,但它不限制扩展名:
final class MyTest {
func testFunc() {}
}
extension MyTest {
func testFunc2() {}
}
let test = MyTest()
test.testFunc2()
这可能吗?
您无法阻止他人向您的 class 添加扩展。就像您无法阻止其他开发人员编写使用您的 class.
的函数一样The
final
modifier only prevents subclassing. Other developers will always be able to add extensions.
真的有问题吗?
恕我直言,它不是。
我们来看看这个class
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())")
}
这在其他几种不支持扩展的编程语言中是可能的。好吧,这基本上是有多少种编程语言可以工作,这也是我们拥有访问控制的原因之一(私有,public,...)。
另一个开发者实际上不能使用我们的 class 的 private
properties/methods(除非它可以访问我们的源文件)。他也不能向 Person
添加属性,因为它是一个标记为 final
的 class,所以 subclassing 是禁止的。他只能编写使用它的代码。
我们都可以接受吗?
然而,编写一个接受参数并仅处理该参数的函数有时很丑陋。函数应该是方法,参数值应该是实例。
所以我们使用扩展来转换这个
func presentAndTellName(person: Person) {
print("Hello everybody! \(person.tellName())")
}
进入这个
extension Person {
func presentAndTellName() {
print("Hello everybody! \(self.tellName())")
}
}
这只是一种编写相同逻辑并使其在 OOP 语法糖中可用的方法。
现在不用写这个
presentAndTellName(person)
我们可以这样写
person.presentAndTellName()
将您的资料设为私有
那么如何保护您的一些 class (/struct) 逻辑和数据不受扩展的影响?使用您用来保护这些东西免受源文件外部函数影响的相同机制,只需将它们标记为 private
。这样其他开发人员将无法将它们用于他们的扩展。
让我们再看看我们的人物 class。
class Person {
private let name: String
func tellName() -> String { return "I am \(name)" }
init(name: String) {
self.name = name
}
}
name
属性 是私有市场,因此 没有办法 并且外部函数或扩展程序将能够直接访问它。
等等,协议呢?
好的,这可能是扩展提供的不仅仅是更好语法的唯一东西。
事实上给定这个协议
protocol Runner {
func run()
}
我们可以符合它 class 我们不拥有
extension Person: Runner {
func run() { print("") }
}