10

我將嘗試使用下面的代碼將邏輯運算符OR||)減少Bool秒的陣列,但是我得到一個錯誤:使用邏輯運算符,結合封閉在減少

func reduceBools(values: [Bool]) -> Bool { 
    return values.reduce(false, combine: ||) 
} 

Ambiguous reference to member '||'

類似於整數的代碼就像一個魅力。

func reduceInts(values: [Int]) -> Int { 
    return values.reduce(0, combine: +) 
} 

我能夠使其通過添加||功能(下面的代碼)或使用{ $0 || $1 }關閉工作,但我不喜歡這些方法,我寧願只是傳遞操作。

func ||(lhs: Bool, rhs: Bool) -> Bool { 
    return lhs || rhs 
} 

同樣的事情發生在邏輯&&)運算符。

如何在不使用上面的黑客的情況下使其工作?

+3

這似乎是一個bug /限制由於'||'和''&&的 「autoclosure」 參數。比較http://stackoverflow.com/questions/28648268/what-is-the-type-of-the-logical-operators和以下評論。 –

+0

@MartinR感謝您的鏈接!我在想,我只是一個愚蠢的人... – user3441734

+0

@MartinR似乎是這樣的情況:/有沒有任何rdar,所以我可以欺騙它? – fpg1503

回答

15

作爲替代方案,你可以用下面的辦法

// || 
func reduceBoolsOr(values: [Bool]) -> Bool { 
    return values.contains(true) 
} 

// && 
func reduceBoolsAnd(values: [Bool]) -> Bool { 
    return !values.contains(false) 
} 

注意.reducecomes with an overhead。如果最終結果是您的問題的重要性(而不是查詢||&&運營商在這種情況下的意外行爲),那麼上面的實用方法可能會有所幫助,即使它並沒有真正減少數組,但由於布爾類型的簡單性質而產生相同的結果。

+1

我認爲在這種情況下使用contains會更好,因爲你描述了你想要的結果得到,而不是如何計算它。它比通常的功能方法更具說明性。 :) –

1

對成員'||'的歧義引用意味着有多個可能的候選人,編譯器無法選擇。在你的情況下,這些都是

public func ||<T : BooleanType, U : BooleanType>(lhs: T, @autoclosure rhs:() throws -> U) rethrows -> Bool 

public func ||<T : BooleanType>(lhs: T, @autoclosure rhs:() throws -> Bool) rethrows -> Bool 

可能是你的「黑客」利用{ $0 || $1 }是這裏最好的解決方案。

+0

它看起來像第二個唯一的原因是,第一個由於錯誤不能是'@ _transparent'。最瘋狂的是他們的實現是相同的。 – fpg1503

0

這是因爲Swifts閉包語義。它採用你的參數並將函數應用於它們,省略參數名稱。

protocol Numeric { 
    ... 
    public static func +(lhs: Self, rhs: Self) -> Self 
    ... 
} 

在例如用整數,你會通過(INT,INT)轉換成閉合,並且在+數字協議功能期望的是兩個整數總結它們。

這就是爲什麼像下面的代碼只是正常

[1, 2, 3, 4].reduce(0, +) 

因爲你只花了2個整數,並應用功能,只需要兩個整數。 如果你編寫你自己的函數,只需要兩個參數,它也可以工作。

func myOwnAwesomeFunc<T: Numeric>(a: T, b: T) -> T { in 
    return 1 // production ready 
} 

[1, 2, 3, 4].reduce(0, myOwnAwesomeFunc) // prints 1 

目前爲止還不錯。但爲什麼我們不能寫

[true, false, true].reduce(false, ||) // yields Cannot invoke 'reduce' 
// with an argument list of type 
// '(Bool, (Bool, @autoclosure() throws -> Bool) throws -> Bool)' 

這是因爲這個運算符采用布爾和閉包,它返回布爾。 不bool,關閉! 但是,如果是這樣,我們爲什麼不寫true || { false }()? 那是因爲@autoclosure,它爲我們照顧大括號。

主要問題,爲什麼它以這種方式實現,所以我們不能使用Swifts真棒短語關閉語法與布爾值? IDK

-1

以下辦法將工作

values.reduce(false) { $0 || $1 }