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 }