swift 学习(一)

来源:互联网 发布:linux内核无法启动 编辑:程序博客网 时间:2024/06/05 08:50

swift学习

一、基础部分

  1. 常量(let) 变量(var
swift能够自己推断变量的类型,可以不用写变量的类型let test = "你好,世界!!"let test:String = "你好,世界!!"var π:Double = 3.14
  1. 类型转换
如果常量和变量的类型不一致,必须把类型转成一致的以后在做运算,但是如果是字面量的话,swift会自动判断类型,所以不用转换字面量:就是表达式右边的值,就叫字面量,let three = 3let pi = 3.14let threeAndPi = (Double)three + pi (正确)let threeAndPi = three + pi          (错误)let threeAndPi = 3 + 3.14
  1. 可选类型(Optional)
    为什么需要Optional,因为非可选类型不能赋值为nil(双击6666),
var surveryAnswer:String = nil (错误)var surveryAnswer:String? = nil (正确)let possibleString: String? = "An optional string."let forcedString: String = possibleString! // 需要感叹号来获取值let assumedString: String! = "An implicitly unwrapped optional string." let implicitString: String = assumedString // 不需要感叹号

基本运算符

  1. 三目运算符 、空和运算符
三目运算符let contentHeight = 40let hasHeader = truelet rowHeight = contentHeight + (hasHeader ? 50 : 20) // rowHeight 现在是 90空合运算符:是为了判断Optional类型为nil的时候,提供默认值,与三目运算符有区别let defaultColorName = "red"var useDefineColorName:String?let defineColorName = useDefineColorName ?? defaultColorName
  1. 区间运算符
    闭区间
    a…b
    半开区间
    a..

集合类型

  1. 数组Arrays
创建空数组var someInts = [Int]()var someInts = []var threeDoubles = Array(repeatElement(0.0, count: 3))一次改变数组中的多个值shoppingList[4...6] = ["Bananas", "Apples"]
  1. 集合Set
创建集合var favoriteGenres:Set<String> = ["Rock","Classical","Hip hop"]移除元素let rock = favoriteGenres.remove("Rock")print(rock!)遍历集合for item in favoriteGenres {print(item)}集合操作• 使用 intersection(_:) 方法根据两个 合中都包含的值创建的一个新的 合。• 使用 symmetricDifference(_:) 方法根据在一个 合中但不在两个 合中的值创建一个新的 合。 • 使用 union(_:) 方法根据两个 合的值创建一个新的 合。• 使用 subtracting(_:) 方法根据不在该 合中的值创建一个新的 合。 let oddDigits: Set = [1, 3, 5, 7, 9] let evenDigits: Set = [0, 2, 4, 6, 8] let singleDigitPrimeNumbers: Set = [2, 3, 5, 7] oddDigits.union(evenDigits).sort() // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] oddDigits. intersection(evenDigits).sorted() // [] oddDigits.subtracting(singleDigitPrimeNumbers).sorted() // [1, 9] oddDigits. symmetricDifference(singleDigitPrimeNumbers).sorted() // [1, 2, 9]
  1. 字典 Dictionary
//创建字典var ariports:[String:String] = ["LHR":"London"]//修改字典ariports.updateValue("ShangHai", forKey: "LHR")ariports["LHR"] = "Asia"//遍历字典for (ariportsCode,ariportsValue) in ariports {print(ariportsCode+":"+ariportsValue)}for ariportsCode in ariports.keys {print(ariportsCode)}for ariportsValue in ariports.values {    print(ariportsValue)}

3.控制流

//闭区间for item in 1...5 {    print(item)}//开区间for item in 1..<5 {    print(item)}//用 _ 忽略item的值var base = 0for _ in 1...5 {    base += 1}print(base) //:  base = 5//while 循环repeat { statements} while condition//switch let someCharacter:Character = "z"switch someCharacter {case "c": //错误 ,case后面必须有语句case "z":    print("The letter first of the alphabat")case "a":    print("The letter last of the alphabat")default:    print("some other character")}switch someCharacter {case "c","z": //正确 ,    print("The letter first of the alphabat")case "a":    print("The letter last of the alphabat")default:    print("some other character")}// 可以用 _ 匹配所有可能的值// 如果存在多个匹配,那么只会执行第一个被匹配到的 case 分支。考虑点(0, 0)会首先匹配 case (0, 0) ,因此剩下的能够匹配的分支都会被忽视掉let anthorPoint = (0,0)switch anthorPoint {case (0,0):    print("origin")case (_,0):    print("_ 0 \(anthorPoint)")case (0,_):    print("0 _ \(anthorPoint)")case (-2...2,-2...2):    print("-2...2 \(anthorPoint)")default:    break}值绑定(Value Bindings)case 分支允许将匹配的值绑定到一个临时的常量或变量,并且在case分支体内使用 —— 这种行为被称为值绑 定(value binding),因为匹配的值在case分支体内,与临时的常量或变量绑定。下面的例子展示了如何在一个 (Int, Int) 类型的元组中使用值绑定来分类下图中的点(x, y): let anotherPoint = (2, 0) switch anotherPoint { case (let x, 0):     print("on the x-axis with an x value of \(x)") case (0, let y):     print("on the y-axis with a y value of \(y)") case let (x, y):     print("somewhere else at (\(x), \(y))") }// 输出 "on the x-axis with an x value of 2"Where

case 分支的模式可以使用 where 语句来判断额外的条件。
下面的例子把下图中的点(x, y)进行了分类:

 let yetAnotherPoint = (1, -1) switch yetAnotherPoint { case let (x, y) where x == y:     print("(\(x), \(y)) is on the line x == y") case let (x, y) where x == -y:     print("(\(x), \(y)) is on the line x == -y") case let (x, y):print("(\(x), \(y)) is just some arbitrary point")}// 输出 "(1, -1) is on the line x == -y"

fallthrough 关键字不会检查它下一个将会落入执行的 case 中的匹配条件。 fallthrough 简单地使代 码继续连接到下一个 case 中的代码,这和 C 语言标准中的 switch 语句特性是一样的

// 验证API的可用性if #available(platform name version, ..., *) {     APIs 可用,语句将执行} else {    APIs 不可用,语句将不执行}

函数

函数返回可以是可选类型 Optional ,当返回值为nil 的时候用可选类型

 func minMax(array: [Int]) -> (min: Int, max: Int)? { if array.isEmpty { return nil } var currentMin = array[0] var currentMax = array[0] for value in array[1..<array.count] {     if value < currentMin {         currentMin = value     } else if value > currentMax {         currentMax = value     }    }     return (currentMin, currentMax) }

你可以在函数名称前指定它的参数标签,中间以空格分隔。可用(_)忽略参数标签

func someFunction(argumentLabel paramterName:Int)->Void {print(paramterName)}someFunction(argumentLabel: 2)

函数参数默认是常量。试图在函数体中更改参数值将会导致编译错误(compile-time error)。这意味着你不能错 误地更改参数值。如果你想要一个函数可以修改参数的值,并且想要在这些修改在函数调用结束后仍然存在,那 么就应该把这个参数定义为输入输出参数(In-Out Parameters)。

func swapTwoInts(_ a: inout Int,_ b: inout Int)->Int{let tempoary:Int = aa = bb = tempoaryreturn tempoary}var aa = 10var bb = 20print(swapTwoInts(&aa, &bb)) // : 10

类和结构体

如果创建了一个结构体struct的实例并将其赋值给一个常量,则无法修改该实例的任何属性,即使有属性被声明为变量也不行,但是类 class 可以修改属性,即使类被定义成常量:

let rangeOfFourItems = FixedLengthRange(firstValue: 0, length: 4) // 该区间表示整数0,1,2,3rangeOfFourItems.firstValue = 6// 尽管 firstValue 是个变量属性,这里还是会报错

延迟存储属性
延迟存储属性是指当第一次被调用的时候才会计算其初始值的属性。在属性声明前使用 lazy 来标示一个延迟存 储属性。

注意必须将延迟存储属性声明成变量(使用 var 关键字),因为属性的初始值可能在实例构造完成之后才会得 到。而常量属性在构造过程完成之前必须要有初始值,因此无法声明成延迟属性。

类型属性用关键字static,如果需要在子类中重写需要用关键字class,类型方法同理,

class ViewMode {static  var interlaced = falsevar frameRate = 0.0var name:String?func someViewMode() {    //这里会出现编译错误,因为`interlaced` 是类型属性,而    // `someViewMode` 方法不能修改类型属性    interlaced = false     //这样写不会报错    ViewMode.interlaced = false}//如果需要修改`interlaced` ,需要把方法定义成类型方法static func someViewMode1() {    interlaced = false}}

注意:结构体和枚举与类有一些区别。结构体和枚举是值类型。默认情况下,值类型的属性不能在它的实例方法中被修改。

struct LevelTracker {static var highestUnlockLevel = 1var currentLevel = 1static func unlocked(level:Int){    if level>highestUnlockLevel {        highestUnlockLevel = level    }}//如果需要访问`currentLevel` 属性,需要把方法定义成`mutating`mutating func someLevel() {    currentLevel = 0}static func isUnlocked(level:Int)->Bool {    return level<=highestUnlockLevel}func somePoperty() {    //这样写也会编译错误    LevelTracker.currentLevel = 1    //这个访问类型属性不会报错    LevelTracker.highestUnlockLevel = 0    }    }

下标

下标允许你通过在实例名称后面的方括号中传入一个或者多个索引值来对实例进行存取。语法类似于实例方法语 法和计算型属性语法的混合。与定义实例方法类似,定义下标使用 subscript 关键字,指定一个或多个输入参数 和返回类型

struct TimesTable {var multiplier:Intsubscript(index:Int)->Int {    get {        return multiplier*index    }    set {        return multiplier = newValue    }}}var threeTimesTable = TimesTable.init(multiplier: 3)threeTimesTable[4] = 4

继承

调用父类的属性和方法用关键字super你可以将一个继承来的只读属性重写为一个读写属性,只需要在重写版本的属性里提供 getter 和 setter 即 可。但是,你不可以将一个继承来的读写属性重写为一个只读属性。

class Vehicle {var currentSpeed = 0.0var description:String {    return "traveling at \(currentSpeed) miles per hour"}func makeNoise() {    }}class Byicle: Vehicle {    var hasBasket = false}let someVehicle = Vehicle()someVehicle.descriptionlet someByicle = Byicle.init()someVehicle.currentSpeed = 30.0someVehicle.description

注意
如果你在重写属性中提供了 setter,那么你也一定要提供 getter。如果你不想在重写版本中的 getter 里修改 继承来的属性值,你可以直接通过 super.someProperty 来返回继承来的值,其中 someProperty 是你要重写的属 性的名字

防止重写 (final)
你可以通过把方法,属性或下标标记为 来防止它们被重写,只需要在声明关键字前加上 修饰符即 可(例如: , , ,以及 )。
如果你重写了带有 标记的方法,属性或下标,在编译时会报错。在类扩展中的方法,属性或下标也可以在 扩展的定义里标记为 final 的。
你可以通过在关键字 前添加 修饰符( )来将整个类标记为 final 的。这样的类是不可 被继承的,试图继承这样的类会导致编译报错。

原创粉丝点击