2016-03-07 122 views
3

我需要用靜態方法創建一個「工具」類或結構。作爲來自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") 
+2

如果你只使用靜態'functions'沒有什麼區別的。但是我發現第三方框架的一些函數不喜歡從'structs'內的'static functions'調用。例如,「解析」背景操作可能會以靜默方式失敗。從來沒有真正花時間弄清楚爲什麼。 –

回答

2

如果你只使用靜態的功能沒有任何區別的。

更多結構可以用structtypealias完成。 (也是如此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

作爲R門客已指出;因爲你沒有這些實用程序類/結構的實例,所以它沒有太大區別。

一個可能投票支持使用類在結構將是,你在其中明確限制在class使用(protocol ...: class)的協議聲明你static功能非常特殊的情況:對於結構對方(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 
    } 
} 

用法示例:

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