swift学习笔记二

前端之家收集整理的这篇文章主要介绍了swift学习笔记二前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

新建一个类,作为计算器的 Model 层,这里将类命名为 CalculatorBrain

import Foundation

class CalculatorBrain {
    //1
    private enum Op {
        case Operand(Double)
        case UnaryOperation(String,Double -> Double)
        case BinaryOperation(String,(Double,Double) -> Double)
    }
    
    //2
    private var opStack = [Op]()
    
    private var knownOps = [String:Op]()
    
    //3
    init() {
        knownOps["×"] = Op.BinaryOperation("×",*)
        knownOps["÷"] = Op.BinaryOperation("÷",{ $1 / $0 })
        knownOps["+"] = Op.BinaryOperation("+",+)
        knownOps["−"] = Op.BinaryOperation("−",{ $1 - $0 })
        knownOps["√"] = Op.UnaryOperation("√",sqrt)
    }
    
    //4
    func evaluate(ops: [Op]) -> (result: Double?,remainOps: [Op])
    {
        if !ops .isEmpty {
            let op = ops.removeLast() // error : Immutable value of type '[CalculatorBrain.Op]' only has mutating members named 'removeLast'
        }
        
        return (nil,ops)
    }
    
    //6
    func pushOperand(operand: Double) {
        opStack.append(Op.Operand(operand))
    }
    
    //7
    func performOperation(symbol: String) {
        if let operation = knownOps[symbol] {
            opStack.append(operation)
        }
    }
}
东西很多,一点一点消化吧,

//1

定义了一个私有的 enum,一般在 object - C 里面我们是这样定义枚举的

typedef NS_ENUM(NSUInteger,HTTPMethod) {
    HTTPMethodGet,HTTPMethodPost,};
但是这里的枚举值却是函数,很奇怪,这个还得去查资料了解一下,先放着.........

//2

声明了一个数组 opStack 和一个字典 knownOps 并初始化。


//3

函数的初始化,为 knownOps 字典赋值,这里比较有趣,BinaryOperation 在定义需要的参数是一个 String 和函数(这个函数需要 2 个 Double 类型的参数,返回值是 Double 类型),而在初始化时这样写 knownOps["÷"] = Op.BinaryOperation("÷",{ $1 / $0 }) 并不奇怪,swift 学习笔记1 里面已经说过了,有趣的是这里的闭包竟然可以直接省略成 * 和 + 就可以代表 (Double,Double) -> Double 了。这是因为在 swift 里所有的操作符都是符号,* 其实就是代表 { $0 * $1 } 了,+ 代表 { $0 + $1 } ,所以可以直接省略写成 * 和 + ,至于 ÷ 和 − 后面的闭包 { $1 / $0 } 和 { $1 - $0 } 不能省略成÷ 和 − ,因为运算方向是相反的。


//4

有两个知识点

1)函数返回的是一个元组(Tuple)

2)这里的 let op = ops.removeLast() 会报错,因为 ops 是一个不可变变量。为什么是一个不可变变量呢?swift 里规定,传过来的参数,除了类之外其他的都是值拷贝,类为引用。数组和字典都是结构体,所以是值拷贝,这点需要牢记。

当然,你可以这样修改

var remainingOps = ops;
let op = remainingOps.removeLast()



--------------------分割线-------------------


完整的 CalculatorBrain 代码如下:

//
//  CalculatorBrain.swift
//  Calculator
//
//  Created by aaron.zheng on 2015-06-27.
//  Copyright © 2015 aaron.zheng. All rights reserved.
//

import Foundation

class CalculatorBrain {
    //1
    private enum Op: CustomStringConvertible {
        case Operand(Double)
        case UnaryOperation(String,Double) -> Double)
        
        var description: String { //要实现自己的 description 就得让 enum 实现 CustomStringConvertible 协议。
            get {
                switch self {
                case .Operand(let operand):
                    return "\(operand)"
                case .UnaryOperation(let symbol,_):
                    return symbol
                case .BinaryOperation(let symbol,_):
                    return symbol
                }
            }
        }
    }
    
    //2
    private var opStack = [Op]()
    
    private var knownOps = [String:Op]()
    
    //3
    init() {
        func learnOp(op: Op) {
            knownOps[op.description] = op
        }
        learnOp(Op.BinaryOperation("×",*)) //下面的同样可以换成用 learnOp。
        knownOps["÷"] = Op.BinaryOperation("÷",sqrt)
    }
    
    //4
    private func evaluate(ops: [Op]) -> (result: Double?,remainOps: [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)
                if let operand = operandEvaluation.result {
                    return (operation(operand),operandEvaluation.remainOps)
                }
            case .BinaryOperation(_,let operation):
                let op1Evaluation = evaluate(remainingOps)
                if let operand1 = op1Evaluation.result {
                    let op2Evaluation = evaluate(op1Evaluation.remainOps)
                    if let operand2 = op2Evaluation.result {
                        return (operation(operand1,operand2),op2Evaluation.remainOps)
                    }
                }
                
            }
        }
        
        return (nil,ops)
    }
    
    //5
    func evaluate() -> Double? {
        let (result,_) = evaluate(opStack) //_ 起占位作用,表示我不关心该参数。
        return result
    }
    
    //6
    func pushOperand(operand: Double) -> Double? {
        opStack.append(Op.Operand(operand))
        return evaluate()
    }
    
    //7
    func performOperation(symbol: String) -> Double? {
        if let operation = knownOps[symbol] {
            opStack.append(operation)
        }
        return evaluate()
    }
}
更多可以看《Developing IOS 8 App With Swift》的 Applying MVC 一节。

猜你在找的Swift相关文章