swift函数重载调用问题

Metaverse 2016-03-14 03:04:31
代码如下,最近在学老头子的swift课程,照代码打,但是Xcode提示我
Ambiguous reference to member 'evaluate'。下面的代码已经把其中一个设置为private,为什么还会出现这种情况,不是应该默认调用我的public函数吗?
private func evaluate(ops:[Op])->(result:Double?,remainingOps:[Op]){

if !ops.isEmpty{
var remainingOps=ops
let op = remainingOps.removeLast()
switch op {
case .Operand(let operand):
return (operand,remainingOps)
//如果是操作符就进行计算
case .UnaryOperation(_, let operation):
let operandEvaluation = evaluate(remainingOps)
//这个时候符号已经被移除,result是第二个操作数
if let operand=operandEvaluation.result{
return (operation(operand),operandEvaluation.remainingOps)
}
case .BinaryOperation(_, let operation):
let op1Evaluation = evaluate(remainingOps)
if let operand1=op1Evaluation.result{
let op2Evaluation = evaluate(op1Evaluation.remainingOps)
if let operand2 = op2Evaluation.result{
return(operation(operand1,operand2),op2Evaluation.remainingOps)
}
}


}
}
return (nil,ops)
}

func evaluate() -> Double? {
let (result , _)=evaluate(opStack)
return result
}

func pushOperand(operand:Double){
opStack.append(Op.Operand(operand))
return evaluate()
}

func performOperation(symbol:String){
if let operation = knowOps[String]{
opStack.append(operation)
}
return evaluate()
}
...全文
270 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
Metaverse 2016-03-14
  • 打赏
  • 举报
回复
太粗心大意了,原来是自己后面的函数没有写返回类型
Metaverse 2016-03-14
  • 打赏
  • 举报
回复
最下面调用evaluate()的时候是无参数的,不是应该匹配无参的evaluate版本吗
Swifter-Swift 开发者必备 Tips (第四版),王巍版本 柯里化 (Currying) Swift 里可以将方法进行柯里化 (Currying),这是也就是把接受多个参数的方法进行一些变形,使其更加灵活的方法。函数式的编程思想贯穿于 Swift 中,而函数的柯里化正是这门语言函数式特点的重要表现。 举个例子,下面的函数简单地将输入的数字加 1: func addOne(num: Int) -> Int { return num + 1 } 这个函数所表达的内容非常有限,如果我们之后还需要一个将输入数字加 2,或者加 3 的函数,可能不得不类似地去定义返回为 num + 2 或者 num + 3 的版本。有没有更通用的方法呢?我们其实可以定义一个通用的函数,它将接受需要与输入数字相加的数,并返回一个函数。返回的函数将接受输入数字本身,然后进行操作: func addTo(_ adder: Int) -> (Int) -> Int { return { num in return num + adder } } 有了 addTo,我们现在就能轻易写出像是 addOne 或者 addTwo 这样的函数了: let addTwo = addTo(2) // addTwo: Int -> Int let result = addTwo(6) // result = 8 再举一个例子,我们可以创建一个比较大小的函数: func greaterThan(_ comparer: Int) -> (Int) -> Bool { return { $0 > comparer } } let greaterThan10 = greaterThan(10); greaterThan10(13) // => true greaterThan10(9) // => false 柯里化是一种量产相似方法的好办法,可以通过柯里化一个方法模板来避免写出很多重复代码,也方便了今后维护。 举一个实际应用时候的例子,在 Selector 一节中,我们提到了在 Swift 中 Selector 只能使用字符串在生成。这面临一个很严重的问题,就是难以重构,并且无法在编译期间进行检查,其实这是十分危险的行为。但是 target-action 又是 Cocoa 中如此重要的一种设计模式,无论如何我们都想安全地使用的话,应该怎么办呢?一种可能的解决方式就是利用方法的柯里化。Ole Begemann 在这篇帖子里提到了一种很好封装,这为我们如何借助柯里化,安全地改造和利用 target-action 提供了不少思路。 protocol TargetAction { func performAction() } struct TargetActionWrapper: TargetAction { weak var target: T? let action: (T) -> () -> () func performAction() -> () { if let t = target { action(t)() } } } enum ControlEvent { case TouchUpInside case ValueChanged // ... } class Control { var actions = [ControlEvent: TargetAction]() func setTarget(target: T, action: @escaping (T) -> () -> (), controlEvent: ControlEvent) { actions[controlEvent] = TargetActionWrapper( target: target, action: action) } func removeTargetForControlEvent(controlEvent: ControlEvent) { actions[controlEvent] = nil } func performActionForControlEvent(controlEvent: ControlEvent) { actions[controlEvent]?.performAction() } } 模式匹配 在之前的正则表达式中,我们实现了 =~ 操作符来完成简单的正则匹配。虽然在 Swift 中没有内置的正则表达式支持,但是一个和正则匹配有些相似的特性其实是内置于 Swift 中的,那就是模式匹配。 当然,从概念上来说正则匹配只是模式匹配的一个子集,但是在 Swift 里现在的模式匹配还很初级,也很简单,只能支持最简单的相等匹配和范围匹配。在 Swift 中,使用 ~= 来表示模式匹配的操作符。如果我们看看 API 的话,可以看到这个操作符有下面几种版本: func ~=(a: T, b: T) -> Bool func ~=(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool func ~=(pattern: I, value: I.Bound) -> Bool 从上至下在操作符左右两边分别接收可以判等的类型,可以与 nil 比较的类型,以及一个范围输入和某个特定值,返回值很明了,都是是否匹配成功的 Bool 值。你是否有想起些什么呢..没错,就是 Swift 中非常强大的 switch,我们来看看 switch 的几种常见用法吧: 可以判等的类型的判断 let password = "akfuv(3" switch password { case "akfuv(3": print("密码通过") default: print("验证失败") } 对 Optional 的判断 let num: Int? = nil switch num { case nil: print("没值") default: print("\(num!)") } 对范围的判断 let x = 0.5 switch x { case -1.0...1.0: print("区间内") default: print("区间外") } 这并不是巧合。没错,Swift 的 switch 就是使用了 ~= 操作符进行模式匹配,case 指定的模式作为左参数输入,而等待匹配的被 switch 的元素作为操作符的右侧参数。只不过这个调用是由 Swift 隐式地完成的。于是我们可以发挥想象的地方就很多了,比如在 switch 中做 case 判断的时候,我们完全可以使用我们自定义的模式匹配方法来进行判断,有时候这会让代码变得非常简洁,具有条理。我们只需要按照需求重载 ~= 操作符就行了,接下来我们通过一个使用正则表达式做匹配的例子加以说明。 首先我们要做的是重载 ~= 操作符,让它接受一个 NSRegularExpression 作为模式,去匹配输入的 String: func ~=(pattern: NSRegularExpression, input: String) -> Bool { return pattern.numberOfMatches(in: input, options: [], range: NSRange(location: 0, length: input.characters.count)) > 0 } 然后为了简便起见,我们再添加一个将字符串转换为 NSRegularExpression 的操作符 (当然也可以使用 StringLiteralConvertible,但是它不是这个 tip 的主题,在此就先不使用它了): prefix operator ~/ prefix func ~/(pattern: String) -> NSRegularExpression { return NSRegular[removed]pattern: pattern, options: nil, error: nil) } 现在,我们在 case 语句里使用正则表达式的话,就可以去匹配被 switch 的字符串了:

1,420

社区成员

发帖
与我相关
我的任务
社区描述
Swift,苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C共同运行于MAC OS和iOS平台,用于搭建基于苹果平台的应用程序。
swift 技术论坛(原bbs)
社区管理员
  • Swift
  • 网罗开发
  • 大熊猫侯佩
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧