2016-10-18 62 views
2

試圖編譯這段代碼使用重載的數學函數

pow(10,2) 
struct Test { 
    var i:Int 
    func pow(_ p:Int) -> Int { return pow(i,p) } 
} 
var s = Test(i:10) 
s.pow(2) 

給我一個編譯器錯誤。很明顯,標準的math.h函數pow被Swift的範圍規則所矇蔽了。由於math.h版本的pow具有不同的簽名,這聽起來像是編譯器錯誤。但是有什麼辦法可以調用它嗎?

+0

這是一個錯誤 - 請參閱[Swift 3.0:調用全局函數時編譯器錯誤最小(T,T)在數組或字典擴展名](http://stackoverflow.com/questions/39602298/swift-3-0 -compiler-錯誤呼全局-FUNC-mintt叔在陣列或 - dicti時)。解決方案是通過使用函數所在的模塊名稱來消除歧義。 – Hamish

+0

儘管在你的情況下,首先沒有對'(Int,Int) - > Int'進行'pow'重載 - 調用'pow(10,2)'實際上使用了重載'(Decimal,Int) - > Decimal ' – Hamish

+0

'pow'返回(並接受)一個十進制數,而不是一個Int - 我認爲編譯器由於類型推斷而丟失。這突然起作用[這些令人討厭的修改](https://www.evernote.com/l/AOxOd1fuS1xElIcTcfPt3E_QldJJf1cBTXU),但它確實看起來像一個編譯器錯誤。 – Moritz

回答

3

有兩個問題:第一個是如何解決pow(i,p)。 如Swift 3.0: compiler error when calling global func min<T>(T,T) in Array or Dictionary extension中所述,可通過將模塊名稱預先添加到函數調用來解決此 。

第二個問題是沒有pow函數取 兩個整數參數。有

public func powf(_: Float, _: Float) -> Float 
public func pow(_: Double, _: Double) -> Double 

標準數學庫,以及

public func pow(_ x: Decimal, _ y: Int) -> Decimal 
在基業庫

。所以,你必須選擇使用哪一個, 例如:

struct Test { 
    var i:Int 
    func pow(_ p:Int) -> Int { 
     return lrint(Darwin.pow(Double(i),Double(p))) 
    } 
} 

其參數轉換爲Double,並將結果取 回Int

可替代地,使用迭代乘法:

struct Test { 
    var i: Int 
    func pow(_ p:Int) -> Int { 
     return (0..<p).reduce(1) { $0.0 * i } 
    } 
} 

我在https://codereview.stackexchange.com/a/142850/35991觀察到 這是小的指數更快。你的旅費可能會改變。