美文网首页
Swift初见(一)

Swift初见(一)

作者: 脚踏实地的小C | 来源:发表于2023-11-27 18:31 被阅读0次

      Swift是一种安全快速互动的编程语言,将现代编程语言的精华和苹果工程师文化的智慧,以及来自开源社区的多样化共享结合了起来。对于初学者的表达力也很友好。是一门满足工业标准,但又有脚本语言表达力可玩性支持代码预览,可以让程序员在不编译和运行程序的前提下运行Swift代码实时查看结果
    通过采用现代编程模式来避免大量常见编程错误:

    • 变量始终在使用前初始化
    • 检查数组索引超出范围的错误
    • 检查整数是否溢出
    • 可选值确保明确处理nil
    • 内存自动管理
    • 错误处理允许从意外故障控制恢复

    简单值

    • 使用let来声明常量,使用var来声明变量
    var myNumber = 42
    myNumber = 50
    let myConstant = 42
    
    • 不同类型的值不能一起相互拼接
    // 编译器会自动推断其类型
    let label = "The width is "
    let width = 94
    let aa = 4.95
    
    // 错误
    let widthLabel = label + width
    let bb = width + aa
    
    // 正确
    let widthLabel = label + String(width)
    let bb = width + Int(aa)
    
    • \()其他类型转为字符串
    let apples = 3
    let oranges = 5
    let appleSummary = "I have \(apples) apples."
    let fruitSummary = "I have \(apples + oranges) pieces of fruit."
    
    • """包含多行字符串内容,
     let apples = 3
     let oranges = 5
     let quotation = """
    I said "I have \(apples) apples."
    And then I said "I have \(apples + oranges) pieces of fruit."
    """
    
    • []创建空数组[:]创建空字典,并使用下标或者来访问元素,
    var shoppingList = ["catfish", "water", "tulips", "blue paint"]
    shoppingList[1] = "bottle of water"
    
    var occupations = [
        "Malcolm": "Captain",
        "Kaylee": "Mechanic",
    ]
    occupations["Jayne"] = "Public Relations"
    
    //空数组和空字典,字典是一个无序的集合
    shoppingList = []
    occupations = [:]
    
    • append添加元素
    shoppingList.append("blue paint")
    print(shoppingList)
    

    控制流

    • 使用ifswitch来进行条件操作
    // if
    let score = 80
    if score > 60 {
       print("及格")
    } else {
       print("不及格")
    }
    *************************************
    // switch 匹配到case语句之后,程序会退出switch语句,不会继续向下运行,所以不需要在每个子句结尾写break
    let vegetable = "red pepper"
    switch vegetable {
    case "celery":
        print("Add some raisins and make ants on a log.")
    case "cucumber", "watercress":
        print("That would make a good tea sandwich.")
    case let x where x.hasSuffix("pepper"):
        print("Is it a spicy \(x)?")
    default:
        print("Everything tastes good in soup.")
    }
    
    • 使用for-inwhilerepeat-while来进行循环
    // for-in
    let individualScores = [75, 43, 103, 87, 12]
    var teamScore = 0
    for score in individualScores {
        if score > 50 {
            teamScore += 3
        } else {
            teamScore += 1
        }
    }
    print(teamScore)
    
    // 在for-in中可以使用"..<"来表示下标范围(不包含上界,如果想包含的话使用"...")
    var total = 0
    for i in 0..<4 {
        total += i
    }
    print(total)
    *************************************
    
    // while
    var n = 2
    while n < 100 {
        n *= 2
    }
    print(n)
    *************************************
    
    // repeat-while
    var m = 2
    repeat {
        m *= 2
    } while m < 100
    print(m)
    

    函数和闭包

    • 使用func来声明一个函数,使用名字和参数来调用函数。使用->来指定函数返回值的类型
    func greet(person: String, day: String) -> String {
        return "Hello \(person), today is \(day)."
    }
    greet(person:"Bob", day: "Tuesday")
    
    • 使用元组来生成复合值,该元组的元素可以用名字数字来获取
    func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
        var min = scores[0]
        var max = scores[0]
        var sum = 0
    
        for score in scores {
            if score > max {
                max = score
            } else if score < min {
                min = score
            }
            sum += score
        }
    
        return (min, max, sum)
    }
    let statistics = calculateStatistics(scores:[5, 3, 100, 3, 9])
    
    //获取元组的元素
    print(statistics.sum)
    print(statistics.2)
    
    • 函数可以嵌套,一般用来重构一个太长或者太复杂的函数
    func returnFifteen() -> Int {
        var y = 10
        func add() {
            y += 5
        }
        add()
        return y
    }
    returnFifteen()
    
    • 函数是第一等类型,这意味着函数可以作为另一个函数的返回值
    func makeIncrementer() -> ((Int) -> Int) {
        func addOne(number: Int) -> Int {
            return 1 + number
        }
        return addOne
    }
    var increment = makeIncrementer()
    increment(7)
    

      看到这里是不是有点懵逼((Int) -> Int)这句呢?((Int) -> Int)表示一个闭包(或函数),接受一个Int参数并返回一个Int。其实你可以这么想,var increment = makeIncrementer()这个拿到了addOne这个函数,然后addOne需要一个为Int类型的参数,所以前面那个(Int)指的是addOne的参数。

    • 函数也可以当作参数传入另一个函数
    func hasAnyMatches(list: [Int], condition: (Int) -> Bool) -> Bool {
        for item in list {
            if condition(item) {
                return true
            }
        }
        return false
    }
    func lessThanTen(number: Int) -> Bool {
        return number < 10
    }
    var numbers = [20, 19, 7, 12]
    hasAnyMatches(list: numbers, condition: lessThanTen)
    

    对象和类

    使用class类名来创建一个类。类中的属性的声明和我们之前看到常量、变量的声明一样,唯一区别是它们的上下文是

    class Shape {
        var numberOfSides = 0
        func simpleDescription() -> String {
            return "A shape with \(numberOfSides) sides."
        }
    }
    
    • 访问
    var shape = Shape()
    shape.numberOfSides = 7
    var shapeDescription = shape.simpleDescription()
    
    • init构造器
    class NamedShape {
        var numberOfSides: Int = 0
        var name: String
    
        init(name: String) {
            self.name = name
        }
    
        func simpleDescription() -> String {
            return "A shape with \(numberOfSides) sides."
        }
    }
    
    // 调用
    let shape = NamedShape(name: "测试")
    shape.numberOfSides = 11
    print(shape.simpleDescription())
    

      这里我们用init来创建一个构造器,这样你创建实例的时候,像传入函数参数一样给类传入构造器的参数

    • deinit析构器
    deinit {
         print("析构器")
     }
    

      与init相对应,通常你不需要使用deinit,当你的实例化对象不在使用时,系统会自动帮你管理内存,如果你需要在对象释放之前进行一些清理工作的话,那么就可以使用deinit创建一个析构函数。

    • override,子类如果重写父类的方法的话,需要用这个标记,不然会报错
    class Square: NamedShape {
        var sideLength: Double
    
        init(sideLength: Double, name: String) {
            self.sideLength = sideLength
            super.init(name: name)
            numberOfSides = 4
        }
    
        func area() ->  Double {
            return sideLength * sideLength
        }
    
        override func simpleDescription() -> String {
            return "A square with sides of length \(sideLength)."
        }
    }
    let test = Square(sideLength: 5.2, name: "my test square")
    test.area()
    test.simpleDescription()
    
    • getset
    var perimeter: Double {
            get {
                return 3.0 * sideLength
            }
            set {
                sideLength = newValue / 3.0
            }
        }
    

      我们这里是声明属性perimeter,然后perimetersetter中,新值的名字是newValue(🌰:xxx.perimeter=1010)

    • willSetdidSet这两个叫做属性观察器,当你不需要计算属性,但是仍然需要设置一个新值之前或者之后运行代码的时候使用
    class aaa {
        var bbb: Int = 0 {
            willSet(newA) {
                print ("new is \(newA)" )
            }   
            
            didSet {
                if bbb > oldValue {     // oldValue是系统层面定义的 对旧值的标签名,不用提前声明,可以直接用。
                    print("increase \(bbb - oldValue)")
                } else {
                    print("new bbb is small than oldValue")
                }
            }
        } 
    }
    

    枚举和结构体

    • 使用enum来创建一个枚举,可以包含方法
    enum Rank: Int {
            case ace = 1
            case two, three, four, five, six, seven, eight, nine, ten
            case jack, queen, king
            func simpleDescription() -> String {
                switch self {
                case .ace:
                    return "ace"
                case .jack:
                    return "jack"
                case .queen:
                    return "queen"
                case .king:
                    return "king"
                default:
                    return String(self.rawValue)
                }
            }
        }
    
    // 调用
    let ace = Rank.ace
    let aceRawValue = ace.rawValue
    

      默认情况下,Swift按照从0开始每次加1的方式为原始值进行赋值,这里我们给ace = 1进行改变,使其从1开始。使用rawValue属性来访问一个枚举成员的原始值。

    • 使用struct来创建一个结构体,结构体和类有很多相同的方法,包括方法和构造器,最大区别是:结构体是传值,类是传引用
    struct Card {
        var rank: Rank
        func simpleDescription() -> String {
            return "The \(rank.simpleDescription()) of aaa"
        }
    }
    
    //调用
    let threeOfSpades = Card(rank: .three)
    let threeOfSpadesDescription = threeOfSpades.simpleDescription()
    

    协议和扩展

    • 使用protocol来声明一个协议
    protocol ExampleProtocol {
        var simpleDescription: String { get }
        mutating func adjust()
    }
    
    • 类、枚举和结构体都可以遵循协议
    // 类
    class SimpleClass: ExampleProtocol {
        var simpleDescription: String = "A very simple class."
        var anotherProperty: Int = 69105
        func adjust() {
            simpleDescription += "  Now 100% adjusted."
        }
    }
    var a = SimpleClass()
    a.adjust()
    let aDescription = a.simpleDescription
    
    // 结构体
    struct SimpleStructure: ExampleProtocol {
        var simpleDescription: String = "A simple structure"
        mutating func adjust() {
            simpleDescription += " (adjusted)"
        }
    }
    var b = SimpleStructure()
    b.adjust()
    let bDescription = b.simpleDescription
    

    mutating关键字用来标记一个会修改结构体的方法

    • 使用 extension 来为现有的类型添加功能,比如新的方法计算属性
    extension Int: ExampleProtocol {
        var simpleDescription: String {
            return "The number \(self)"
        }
        mutating func adjust() {
            self += 42
        }
    }
    print(7.simpleDescription)
    

    未完待续.....

    相关文章

      网友评论

          本文标题:Swift初见(一)

          本文链接:https://www.haomeiwen.com/subject/zkizwdtx.html