我参加了斯坦福大学IOS 9开发者课程的第二讲。讲师正试图建立一个计算器。我无法弄清楚两个部分。 之一:
if pending != nil {
accumulator = pending!.binaryFunction(pending!.firstOperand, accumulator)
pending = nil
我知道待处理是可选的。但是为什么当我把它嵌套在" IF"中时,我仍然必须强行打开它。检查是否为零的陈述?
第二部分是:
private struct PendingBinaryOperationInfo {
var binaryFunction: (Double, Double) -> Double
var firstOperand: Double
}
为什么这两个变量不需要初始化器?是因为它在"结构"?
之下整个代码如下。我不理解的两个部分位于块的底部。
非常感谢!
import Foundation
class CalculatorBrain
{
private var accumulator = 0.0
func setOperand(operand: Double) {
accumulator = operand
}
private var operations: Dictionary<String,Operation> = [
"e" : Operation.Constant(M_E),
"√" : Operation.UnaryOperation(sqrt),
"cos" : Operation.UnaryOperation(cos),
"×" : Operation.BinaryOperation({ $0 * $1 }),
"÷" : Operation.BinaryOperation({ $0 / $1 }),
"+" : Operation.BinaryOperation({ $0 + $1 }),
"−" : Operation.BinaryOperation({ $0 - $1 }),
"=" : Operation.Equals
]
private enum Operation {
case Constant(Double)
case UnaryOperation ((Double) -> Double)
case BinaryOperation ((Double, Double) -> Double)
case Equals
}
func performOperation(symbol: String) {
if let operation = operations[symbol] {
switch operation {
case .Constant(let value):
accumulator = value
case .UnaryOperation(let function):
accumulator = function(accumulator)
case .BinaryOperation(let function):
executePendingBinaryOperation()
pending = PendingBinaryOperationInfo(binaryFunction: function, firstOperand: accumulator)
case .Equals:
executePendingBinaryOperation()
}
}
}
private func executePendingBinaryOperation()
{
if pending != nil {
accumulator = pending!.binaryFunction(pending!.firstOperand, accumulator)
pending = nil
}
}
private var pending: PendingBinaryOperationInfo?
private struct PendingBinaryOperationInfo {
var binaryFunction: (Double, Double) -> Double
var firstOperand: Double
}
var result: Double {
get {
return accumulator
}
}
}
答案 0 :(得分:1)
if pending != nil { accumulator = pending!.binaryFunction(pending!.firstOperand, accumulator) pending = nil
为什么当我将它嵌套在一个时,我仍然必须强行打开它 “IF”声明检查它是否为零?
Swift是一种强类型语言。在这种情况下,pending
的类型为PendingBinaryOperationInfo?
。仅仅因为您选中它以确保它不是nil
并不会改变pending
类型为PendingBinaryOperationInfo?
的事实。您仍然需要打开它以访问由Optional包含的PendingBinaryOperationInfo
。
对nil
的检查只是确保您可以安全地将pending
与!
解包,因为您现在知道它不会因pending
nil
而崩溃}。
有时,程序员会这样写:
if let unwrappedPending = pending {
accumulator = unwrappedPending.binaryFunction(unwrappedPending.firstOperand, accumulator)
pending = nil
这使用可选绑定来展开pending
并将其分配给unwrappedPending
类型的新变量PendingBinaryOperationInfo
(不< / em>可选)。
有时,您可能也会看到:
if let pending = pending {
accumulator = pending.binaryFunction(pending.firstOperand, accumulator)
pending = nil // Oh, but this won't work because pending isn't optional
在这种情况下,会创建一个类型为pending
的新变量PendingBinaryOperationInfo
,它会隐藏原始pending
变量。我个人不喜欢这种形式,因为它将问题与两个具有相同名称的不同类型的两个不同变量混淆。在这种情况下,它无论如何都不会起作用,因为作者还希望将pending
设置为nil
,并且您无法再访问{{1}内的原始可选pending
}}
第二部分是:
if
为什么这两个变量不需要初始化器?是因为它处于“结构”之下?“
是。对于结构,Swift会自动为您生成初始化程序,以初始化所有属性。您可以通过键入以下内容来使用Xcode的自动填充功能查看此初始化程序:
private struct PendingBinaryOperationInfo {
var binaryFunction: (Double, Double) -> Double
var firstOperand: Double
}
只要您输入PendingBinaryOperationInfo(
,初始化程序就会弹出建议的完成时间。这是一个游乐场:
答案 1 :(得分:0)
您正在检查nil
,但对象尚未解开,您可以做的就是这样
if let pending = pending { ... }
问题的第二部分,struct
中的变量不是nil
因此,当您初始化PendingBinaryOperationInfo
时,必须使用non-null
值初始化它,您可以通过在struct
答案 2 :(得分:0)
变量累加器不是可选的,不能变为nil,这就是为什么你必须强制解包挂起的可选项而不能使用可能返回nil的可选链接问号(?)的原因。
结构PendingBinaryOperationInfo没有默认值,因此必须初始化。