静态类与静态结构的静态工具操作?
我需要创build一个“工具”类或结构只有静态方法。 作为来自PHP背景的人,结构并不存在。
我正在阅读关于这个为什么select结构上课? 但是他们不会谈论静态结构或静态类。
我应该使用哪些永远不会实例化的静态方法,为什么?
例:
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")
如果您只使用静态函数,则完全没有区别。
更多的结构可以用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)
正如R门科已经指出的那样, 因为你没有这些实用程序类/结构的实例,所以没有太大区别。
一个可能的投票使用类比结构将是非常具体的情况下,你声明你的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
:class
约束并不真正相关。 但是,如果MyClassProtocol
协议(除了包含静态工具)被用作上下文中的委托,则是相关的,这个委托的强有力的参考将创build一个保留周期。 在这种情况下,我们需要限制委托协议只能用于引用types(为了一致性),这使我们能够对委托本身使用弱引用。 在这种情况下,自然我们的工具箱必须在class
上下文中使用(而不是在结构中)。
例如,考虑下面的例子,我们有一些静态工具箱的function,我们希望提供给所有不同types的代表:
/* 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 } }
用法示例:
var a = Foo() var b = Bar(foo: a) a.baz.append(1) // idx updated: 1 <-- from custom delegate // Logging: delegate was called <-- from delegate toolbox