2016-09-25 20 views
2

我是新來的靜態類型的語言,並想知道是否有可能將一個Struct類型轉換爲它的類型來調用正確的重載函數?我遇到的問題是我有一個符合Mutation協議的結構列表。我想遍歷列表併爲每個Struct調用正確的handle函數。我會這樣handle功能移動到結構本身,而是我想實現API我想看看如果這樣的事情是可能的,如下:對於實現相同協議的不同結構重載函數?

//: Playground - noun: a place where people can play 

import UIKit 

protocol Mutation { 
    func mutate(state: Int) -> Int 
} 

struct CountIncrement: Mutation { 
    func mutate(state: Int) -> Int { 
     return state + 1 
    } 
} 

struct CountDecrement: Mutation { 
    func mutate(state: Int) -> Int { 
     return state - 1 
    } 
} 

func handle(mutation: CountIncrement, state: Int) -> Int { 
    print("WILL INCREMENT") 
    return mutation.mutate(state: state) 
} 

func handle(mutation: CountDecrement, state: Int) -> Int { 
    print("WILL DECREMENT") 
    return mutation.mutate(state: state) 
} 

var state = 0 
var queue = [CountIncrement(), CountDecrement()] as [Mutation] 

for mutation in queue { 
    handle(mutation: mutation, state: state) // error: cannot invoke 'handle' with an argument list of type '(mutation: Mutation, state: Int)' 
} 

回答

1

這是你應該如何處理問題的倒退。在Swift中,通常應該避免使用免費函數(如handle(mutation:state:)),而是將方法附加到類型中。

你的循環想要一個特定的方法,所以你需要一個新的協議(當然你可以將這個函數附加到Mutation,但將它分開意味着它可以有不同的訪問控制或類似的東西,免費功能)。

protocol MutationHandling { 
    func handleMutation(forState state: Int) -> Int 
} 

所以我們剛剛宣佈這個功能是你想要的。現在我們可以將它附加到我們關心的事情上。這和你上面寫的自由函數完全一樣。這是一樣的模式。語法不同,並提供了一些有關爲何存在此功能的額外文檔,並允許IDE提供自動完成並更有效地收集文檔。

extension CountIncrement: MutationHandling { 
    func handleMutation(forState state: Int) -> Int { 
     print("WILL INCREMENT") 
     return mutate(state: state) 
    } 
} 

現在,你用這個特殊的協議列表:

var queue = [CountIncrement(), CountDecrement()] as [MutationHandling] 

,並稱之爲:

for mutation in queue { 
    mutation.handleMutation(forState: state) 
} 

這不是斯威夫特只是一些隨機的限制。這是Swift如何分解問題的深層原因。自由函數被明確勸阻(見API Design Guidelines)。方法和擴展是Swift方法。

1

您可以將您的handle()功能,如這一點,並接受對參數mutation所有符合您的協議Mutation對象:

func handle(mutation: Mutation, state: Int) -> Int { 
    return mutation.mutate(state: state) 
} 

這樣做的原因:

queue[Mutating]的類型。因此,您的for-Loop中的mutation將是Mutation。目前,您沒有handle()函數,它接受Mutation作爲參數。

相關問題