xiwenAndlejian / my-blog

Java基础学习练习题
1 stars 0 forks source link

iOS学习笔记(二)基础篇(中) #8

Open xiwenAndlejian opened 6 years ago

xiwenAndlejian commented 6 years ago

iOS学习笔记(二)基础篇(中)

学习笔记来自https://www.hackingwithswift.com/read/0

环境版本:

函数

基本定义:


// 函数定义
func functionName(param: Type) -> ReturnType {
    ...code
    return result
}
// 调用,此处使用的两个 param ,前一个是外部参数,后一个是变量
functionName(param: param)

省略外部参数:

// 如果函数是如下定义,即在内部参数前,调用时可不使用外部参数
func functionName(_ param: Type) -> ReturnType {
    ...code
    return result
}
// 不带参数名称
functionName(param)

内外使用不同的参数:

// 定义
func countLetters(in string: String) {
    // 注意函数内部使用的参数是 string
    print("The string \(string) has \(string.count) letters.")
}

// 调用,注意传入使用的参数是 in
countLetters(in: "Hello")

Optionals(可选项?)

类似于Java中的Optional类 在函数有返回值,且返回值可能为空时就可以使用

// 注意函数返回值后的空格
func getHaterStatus(weather: String) -> String? {
    if weather == "sunny" {
        return nil
    } else {
        return "Hate"
    }
}

// 获取返回值
// 方法1
var status1: String?
status1 = getHaterStatus(weather: "rainy")
// 方法2
var status2 = getHaterStatus(weather: "sunny")

// 使用 optional
// 方法1:自动解包
if let unwrappedStatus = status1 {
    // status1 有值时执行的代码
} else {
    // status1 == nil 时执行的代码
}

// 方法二:强制解包
if status1 == nil {
    // 变量没值,或许应该抛出异常
} else {
    // 变量有值,执行操作
    // 注意变量后面的 !,如果没有感叹号,变量会额外输出 Optional("Hate")
    print("The Hater status: \(status1!)")
}

!:表示确定变量有值,所以强行打开,如果打开一个值为nil,则程序会崩溃(没实际测试过)

Optional Chaining

继续使用上一节的函数

func getHaterStatus(weather: String) -> String? {
    if weather == "sunny" {
        return nil
    } else {
        return "Hate"
    }
}

let status = getHaterStatus(weather: "rainy")
// 不判空强行解包,不推荐模仿
print("The Hater Status: \(status!.uppercased())")

我们可以将上述代码中最后两行稍加修改,代码如下:


let status = getHaterStatus(weather: "rainy")?.uppercased()
print("The Hater Status: \(status)")

注意表达式中的?,这就是optional chaning:问号后面所有的内容只在问号前所有的内容都有值时才会运行。 可以使用多次?

let status = getHaterStatus(weather: "rainy")?.someOptionalValue?.someOtherOptionalValue?...

The nil coalescing operator:??

??:零合并操作符, 使用:

let status = getHaterStatus(weather: "rainy") ?? "unknown"
// 当 ?? 左边表达式为空时,则使用右边的表达式
print("The Hater Status: \(status)")

枚举

// 定义
enum WeatherType {
    case sun
    case cloud
    case rain
    case wind
    case snow
}

func getHaterStatus(weather: WeatherType) -> String? {
    if weather == .sun {
        return nil
    } else {
        return "Hate"
    }
}

// 使用
getHaterStatus(weather: .cloud)

枚举附加值


// 定义
enum WeatherType {
    case sun
    case cloud
    case rain
    case wind(speed: Int)
    case snow
}

func getHaterStatus(weather: WeatherType) -> String? {
    switch weather {
    case .sun:
        return nil
    case .wind(let speed) where speed < 10:
        return "meh"
    case .cloud, .wind:
        return "dislike"
    case .rain, .snow:
        return "hate"
    }
}
// 使用
getHaterStatus(weather: WeatherType.wind(speed: 5))

Struct:结构


// 定义
struct Person {
    var clothes: String
    var shoes: String
}

// 使用
let taylor = Person(clothes: "T-shirts", shoes: "sneakers")
let other = Person(clothes: "short skirts", shoes: "high heels")

print(taylor.clothes)// 输出:T-shirts
print(other.shoes)// 输出:high heels

复制struct

// 跟上文代码

var taylorCopy = taylor
taylorCopy.shoes = "flip flops"

print(taylor)
print(taylorCopy)
// 分别输出
// Person(clothes: "T-shirts", shoes: "sneakers")
// Person(clothes: "T-shirts", shoes: "flip flops")

struct变量赋值给另一个变量,并不是别名,而是复制了原结构变量的值,之后的修改互不影响。

结构中定义函数

// 修改结构定义
struct Person {
    var clothes: String
    var shoes: String

    func describe() {
        print("I like wearing \(clothes) with \(shoes)")
    }
}

let taylor = Person(clothes: "T-shirts", shoes: "sneakers")
// 调用结构的函数
taylor.describe()

Class:类

ClassStruct有很多相同之处,但也有很多不同之处: 网站原文:

  • You don't get an automatic memberwise initializer for your classes; you need to write your own.
  • You can define a class as being based off another class, adding any new things you want.
  • When you create an instance of a class it’s called an object. If you copy that object, both copies point at the same data by default – change one, and the copy changes too.

机翻(略作修改):

class Person { var clothes: String var shoes: String

// 如果没有 init 方法,则编译器会提示错误
init(clothes: String, shoes: String) {
    self.clothes = clothes
    self.shoes = shoes
}

}


#### 继承

##### 重写
```swift
class Singer {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func sing() {
        print("La la la la")
    }
}

class CountrySinger: Singer {
    // 覆盖父类中的同名方法
    override func sing() {
        print("Trucks, guitars, and liquor")
    }
}

var taylor = CountrySinger(name: "Taylor", age: 25)
taylor.sing()// 输出:Trucks, guitars, and liquor
新的属性

 class HeavyMetalSinger: Singer {
    var noiseLevel: Int
    // 相应的修改他的 init 方法
    init(name: String, age: Int, noiseLevel: Int) {
        self.noiseLevel = noiseLevel
        super.init(name: name, age: age)
    }

    override func sing() {
        print("Grrrrr rargh rargh rarrrrgh!")
    }
}

如何选择使用类还是结构

原文:

This is an important difference, and it means the choice between structs and classes is an important one:

  • If you want to have one shared state that gets passed around and modified in place, you're looking for classes. You can pass them into functions or store them in arrays, modify them in there, and have that change reflected in the rest of your program.
  • If you want to avoid shared state where one copy can't affect all the others, you're looking for structs. You can pass them into functions or store them in arrays, modify them in there, and they won't change wherever else they are referenced. If I were to summarize this key difference between structs and classes, I'd say this: classes offer more flexibility, whereas structs offer more safety. As a basic rule, you should always use structs until you have a specific reason to use classes.

机翻: