我需要使用静态方法创建“工具”类或结构。作为来自PHP背景的人,结构不存在。
我正在阅读这篇Why Choose Struct Over Class?,但他们没有谈论静态结构或静态类。
我应该将哪些用于从未实例化的静态方法?为什么?
示例:
struct BasicTools {
static func split(str: String) -> [String]{
return str.characters.split{$0 == ","}.map(String.init)
}
}
VS
class BasicTools {
static func split(str: String) -> [String]{
return str.characters.split{$0 == ","}.map(String.init)
}
}
使用中:
let StrArr: [String] = BasicTools.split("example,example2,example3")
答案 0 :(得分:3)
如果您只使用静态功能,则完全没有区别。
使用struct
和typealias
可以完成更多结构。 (对于class
也是如此,但没有双关语)
struct MathUtils {
static func someMaths(withInt int:Int) -> Int {
return int
}
}
struct StringUtils {
static func someEditing(withString string:String) -> String {
return string
}
}
struct Utils {
typealias Maths = MathUtils
typealias Strings = StringUtils
}
Utils.Maths.someMaths(withInt: 10)
答案 1 :(得分:1)
正如R Menke已经指出的那样;因为你没有这些实用程序类/结构的实例,所以它并没有太大的区别。
在结构上使用类的一个可能投票将是针对特定情况,即您在一个协议中声明window.addEventListener("keydown", function(e) {
if(e.keyCode == 38) {
alert('BOOYAKA');
}
}, false);
函数,该协议特别限制为static
用法(class
):结构的对应物(protocol ...: class
)不可用。
protocol ...: struct
在您的上下文(仅实用工具的类/结构)中,/* only class types can conform to this protocol */
protocol MyClassProtocol: class {
static func split(str: String) -> [String]
}
extension MyClassProtocol {
static func split(str: String) -> [String]{
return str.characters.split{$0 == "."}.map(String.init)
}
}
/* Use custom implementation */
class BasicTools: MyClassProtocol {
class func split(str: String) -> [String]{
return str.characters.split{$0 == ","}.map(String.init)
}
}
/* Use default implementation */
class OtherBasicTools: MyClassProtocol { }
BasicTools.split("foo,bar") // ["foo", "bar"]
OtherBasicTools.split("foo.bar") // ["foo", "bar"]
的上述:class
约束并不真正相关。然而,如果MyClassProtocol
协议---除了包含静态工具---在上下文中被用作委托之外,那么这个委托的强引用会创建一个保留周期。在这种情况下,我们需要将委托协议限制为仅对引用类型可用(对于一致性),这允许我们使用对委托本身的弱引用。在这种情况下,我们的工具箱自然必须在MyClassProtocol
上下文中使用(而不是在结构中)。
,例如,考虑以下示例,其中我们有一些静态工具箱,我们希望为所有不同类型的代表提供这些功能:
class
由一些代表在这里使用:
/* Delegate toolbox: static/class functions for use
with your delegates */
protocol MyBasicDelegateTools {
static func delegateCalled() -> ()
}
extension MyBasicDelegateTools {
static func delegateCalled() -> () {
print("Logging: delegate was called")
}
}
使用示例:
/* Delegate with access to your basic delegate tools */
protocol MyDelegate: class, MyBasicDelegateTools {
func arrUpdated(baz: [Int])
}
/* It's inherrent here that we let the reference to
the delegate be weak, to avoid a retain cycle. */
class Foo {
private var baz : [Int] = [] {
didSet {
if let _ = delegate?.arrUpdated(baz) {
delegate?.dynamicType.delegateCalled()
}
}
}
weak var delegate: MyDelegate?
}
/* Why? Since 'foo' in 'Bar' keeps a strong reference to the 'Foo' instance */
class Bar: MyDelegate {
var foo : Foo
var idx: Int = 0 {
didSet {
print("idx updated: \(idx)")
}
}
init(foo: Foo) {
self.foo = foo
self.foo.delegate = self
}
// MyDelegate
func arrUpdated(baz: [Int]) {
idx = baz.count
}
}