2015-05-26 71 views
1

在數組擴展中創建通用函數時發現了這個隱晦的問題。比方說,我有用戶類,我會用它來創建數組:在數組擴展中使用通用函數中的追加

class User : NSObject { 
    let name : String 
    let surname : String 

    init(name : String, surname : String) { 
     self.name = name 
     self.surname = surname 
    } 

    override var description : String { 
     return self.name + " " + self.surname 
    } 
} 

注意,我需要它是NSObject的子類。現在讓我們創建兩個用戶並將其添加到用戶數組中。

var user1 = User(name: "Jimmy", surname: "Page") 
var user2 = User(name: "David", surname: "Guilmour") 

var users = Array<User>() 
users.append(user1) 
users.append(user2) 

現在我需要數組擴展特定於陣列,或者用戶的任何其他子類的功能,這將一些測試用戶添加到用戶的任何陣列。原因我寫在擴展名,而不是我自己的類型,因爲我想檢查它的類型使用if let something = something as [User]。如果我建立自己的類型,我就無法做到這一點。

extension Array { 
    mutating func addTestUsers<T : User>() { 
     var testUser1 = User(name: "King", surname: "Brown") 
     var testUser2 = User(name: "Carlos", surname: "Santana") 
     self.append(testUser1) 
     self.append(testUser2) 
    } 
} 

問題來了,當使用追加函數或任何其他函數可以以某種方式改變初始數組。

錯誤:Cannot invoke append with argument list of type (User)

我知道這是因爲擴展從未指定爲用戶的陣列的擴展,但我可以看到有沒有辦法,我可以做到這一點。

+2

您*不能*定義一個數組擴展方法,它只適用於數組的用戶,請參閱http://stackoverflow.com/questions/24938948/array-extension-to-remove-object-by-value或http ://stackoverflow.com/questions/27350941/is-it-possible-to-make-an-array-extension-in-swift-that-is-restricted-to-one-cla。 –

回答

0

正如@馬丁的r評論所說,如果你在Array extension to remove object by value一看,最高的投票答案提示寫一個函數,它接受一個數組作爲參數,你的情況,你可以這樣做:

func addTestUsers(inout array: [User]) { 
    let user1 = User(name: "King", surname: "Brown") 
    let user2 = User(name: "Carlos", surname: "Santana") 
    array += [user1, user2] 
} 

然後,您可以使用此像這樣:

var array = [User(name: "Jimmy", surname: "Page")] 
addTestUsers(&array) // [Jimmy Page, King Brown, Carlos Santana] 

如果您打算創建的User子類,但是,以前的方法是不合適的,因爲你將無法通過子類的數組作爲參數。在這種情況下,你可以重寫addTestUsers接受你的子類,但一個更優雅的解決方案可能是:

func addTestUsers<T: User>(inout array: [T]) { 
    let user1 = T(name: "King", surname: "Brown") 
    let user2 = T(name: "Carlos", surname: "Santana") 
    array += [user1, user2] 
} 

對於以前功能工作,你需要在標記init(name : String, surname : String)Userrequired

class User : NSObject { 
    // ... 
    required init(name : String, surname : String) { 
     self.name = name 
     self.surname = surname 
    } 
    // ... 
} 

標記爲required意味着User必須執行init(name : String, surname : String)的任何子類,因此可以安全使用T(name: "...", surname: "...")addTestUsers