Swift语言学习日志--1

Swift语言学习日志–总览篇

写在前面:这篇文章是关于Swift语言的一个大概全貌的基本了解,是基于文尾的链接写的,写的比较简略,看完之后可以开始动手写一些简单的Swift代码,详细的各个知识点后续再更新

变量与常量

定义

   var myVariable = 42
    myVariable = 50
    let myConstant = 42

var表示变量 let表示常量

let explicitDouble: Double = 70

带有显式定义的类型的常量

类型转换

let label = "The width is "
let width = 94
let widthLabel = label + String(width)
True
let label = "The width is "
let width = 94
let widthLabel = label + width
False

在Swift语言中没有隐式转换 需要转换只能是显示转换

let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."

\()可以进行字符串中的计算以及表达式的使用

多行字符串

let quotation = """
I said "I have \(apples) apples."
And then I said "I have \(apples + oranges) pieces of fruit."
"""

多行字符串使用""" """

字典和数组

var shoppingList = ["catfish", "water", "tulips"]
shoppingList[1] = "bottle of water"

print(shoppingList)
//["catfish", "bottle of water", "tulips"]

var occupations = [
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
]
occupations["Jayne"] = "Public Relations"

print(occupations)
/*
[
    "Malcolm": "Captain",
    "Kaylee": "Mechanic",
    "Jayne":"Public Relations"
]
*/

key-value key可以用来检索,不一定是String类型

let emptyArray = [String]()
let emptyDictionary = [String: Float]()

创建空数组或字典

控制流

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)
// Prints "11"

这里score的默认为let常量,不可以在循环中改变或者赋值,如果需要赋值或者改变的话需要这样写:

for var score in individualScores{
......
score = 5
}

这样就可以给他赋值了

可选值的使用

var optionalString: String? = "Hello"
print(optionalString == nil)
// Prints "false"

var optionalName: String? = "John Appleseed"
var greeting = "Hello!"
if let name = optionalName {
    greeting = "Hello, \(name)"
}

这里String?相当于一种新类型,表示可以为空,运用这种类型时要注意检查它是否为空,同时输出时直接输出得到的结果和一般的字符串不一样

print(optinalString)
//optinal("Hello")

如果要得到正常输出请使用

print(optinalString!)
//Hello

最后这段代码的意思等同于

if let name = optionalName {
    greeting = "Hello, \(name)"
}

//等同于

if optinalName != nil {
let name = optianlName
greeting = "Hell0,\(name)"
}

处理可选值的??方式

let nickName: String? = nil
let fullName: String = "John Appleseed"
let informalGreeting = "Hi \(nickName ?? fullName)"

switch-case结构

这里第三个Case中表示如果x并且x中符合where后面的布尔表达式(x.hasSuffix()是一个函数返回布尔值)则执行case后面的代码

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.")
}
// Prints "Is it a spicy red pepper?"

字典中的for-in结构

对字典的迭代循环

let interestingNumbers = [
    "Prime": [2, 3, 5, 7, 11, 13],
    "Fibonacci": [1, 1, 2, 3, 5, 8],
    "Square": [1, 4, 9, 16, 25],
]
var largest = 0
for (kind, numbers) in interestingNumbers {
    for number in numbers {
        if number > largest {
            largest = number
        }
    }
}
//kind为标签 numbers为值数组
print(largest)
// Prints "25"

范围表示

m..<n表示范围[m,n)m...n表示范围[m,n]

var total = 0
for i in 0..<4 {
    total += i
}
print(total)
// Prints "6"

功能和闭包

函数的声明

函数中的输入参数带有标签(名字)和类型,调用的时候要记得带上函数的标签来使用如下:

func greet(person: String, day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet(person: "Bob", day: "Tuesday")

如果确实为不需要标签,我们可以使用_来表示

func greet(_ person: String, on day: String) -> String {
    return "Hello \(person), today is \(day)."
}
greet("John", on: "Wednesday")

函数需要返回多个值时,可以使用元组来完成

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)
// Prints "120"
print(statistics.2)
// Prints "120"

函数也可以嵌套使用

func returnFifteen() -> Int {
    var y = 10
    func add() {
        y += 5
    }
    add()
    return y
    //y 15
}
returnFifteen()

函数可以使用函数作为返回值,类似于C++中的函数指针

func makeIncrementer() -> ((Int) -> Int) {
    func addOne(number: Int) -> Int {
        return 1 + number
    }
    return addOne
}
var increment = makeIncrementer()
increment(7)

当然函数也可以作为参数

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)

闭包的使用

numbers.map({ (number: Int) -> Int in
    let result = 3 * number
    return result
})

对象和类

类的创建,init为初始化,self类本身,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()

get和set为变量设置属性,这种方法还可以使关联变量保持一致

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0

   init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }

   var perimeter: Double {
        get {
            return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }

   override func simpleDescription() -> String {
        return "An equilateral triangle with sides of length \(sideLength)."
    }
}



   

var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")

print(triangle.perimeter)

此处调用perimeter的get函数

    // Prints "9.3"

triangle.perimeter = 9.9

此处调用perimeter的set函数

print(triangle.sideLength)
// Prints "3.3000000000000003"

枚举与结构体

枚举

枚举类型中第一个默认值为0,除非如下设置起始值,后面的量递加,与C/C++一样

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

结构体

结构体的关键字为struct与C/C++一样,可以定义不同的变量的结构,其中可以设置一些常用的函数,结构体带有默认的初始化函数,这点与类不一样

struct Card {
    var rank: Rank
    var suit: Suit
    func simpleDescription() -> String {
        return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
    }
}
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()

协议和扩展

协议

协议用关键字protocol来定义,协议是用来约束和规定某些规范的,当类或者是结构体接受某种协议时,与其继承父类属性类似,必须遵从协议的规范,如下面的简单的协议,协议表明,其中必须有一个名为simpleDescription的变量,其类型为String,还必须有一个函数adjust

    protocol ExampleProtocol {
        var simpleDescription: String { get }
        mutating func adjust()
    }

如下类接受了上述的协议,则其中必须上述要素,当在xcode中编写代码时,接受协议而没有按照约定规范书写时,会出现编译错误,此时点击警告中的·FIX按钮,则xcode会自动添加规范代码

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += "  Now 100% adjusted."
    }
}

扩展

扩展用关键字extension来扩展已经定义好的类或者结构体,增加我们需要的功能,如下代码中扩展Int中的功能,增加了协议ExampleProtocol,扩展了我们需要的功能

    extension Int: ExampleProtocol {
        var simpleDescription: String {
            return "The number \(self)"
        }
        mutating func adjust() {
            self += 42
        }
    }
    print(7.simpleDescription)
    // Prints "The number 7"

错误处理

错误处理是为了处理一些错误情况,用关键字throw来定义,try catch类处理错误,如果没有发生错误则正常执行try模块,否则调其catch模块处理错误。如下代码先定义了三个错误类型,函数中使用错误处理模块,如果出现错误情况,则向系统抛出异常

    enum PrinterError: Error {
        case outOfPaper
        case noToner
        case onFire
    }
    func send(job: Int, toPrinter printerName: String) throws -> String {
        if printerName == "Never Has Toner" {
            throw PrinterError.noToner
        }
        return "Job sent"
    }



    do {
        let printerResponse = try send(job: 1040, toPrinter: "Bi Sheng")
        print(printerResponse)
    } catch {
        print(error)
    }
    // Prints "Job sent"

范型

范型的使用有利于代码的复用,与C/C++类似,定义以及使用如下

    func makeArray<Item>(repeating item: Item, numberOfTimes: Int) -> [Item] {
        var result = [Item]()
        for _ in 0..<numberOfTimes {
            result.append(item)
        }
        return result
    }
    makeArray(repeating: "knock", numberOfTimes: 4)

参考Swift官方文档:
Swift Tour文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值