跟着官方2016的入门学习. https://developer.apple.com/videos/play/wwdc2016/404/

第一段 fundamental - 基础介绍

常量和变量

let inte : Int = 2000 //常量
let inte = 2017 // 可以省略类型, 如果系统可以推断的话
var intevar = 100 //变量
intevar = 200 
let conf = "wwdc"
let message = "hello, \(conf) \(inte+1)!"

字典和数组

//字典和数组
let names=["lilly", "santiaooo", "drurrrr", "daaaad"]
let ages=["dad": 47, "mom": 36, "son": 27]

循环

// 循环  let endOfFile = true
while !endOfFile{
    //readline()
} //let tasksremaining = -1
repeat{
    //preformtask()
}while tasksremaining>0
let xxxstring = "dog?:~!"
for i in xxxstring.characters{ // in names 数组也行
    print()
}
for i in 0...10{ // 0..<10
    print("\(i) times is  \(i*4)")
}
for (name, age) in ages { //(name, age) 是一个元组turple
	print("\(name) is \(age) years old")
}

修改字典和数组

修改数组和字典
var packagelist = ["socks", "shoes"]
print(packagelist[0])
packagelist.append("throusers")
packagelist[2] = "jeans"
packinglist.append(contentsOf: ["shorts","sandals","sunblock"])
packinglist[3...5]=["hoodie", "scarf"]
修改字典
var ages=["dad": 47, "mom": 36, "son": 27]
ages["daughter"]="16" // add a element: daughter
ages["daughter"]="18" // change the element: daughter

optinal 可选内容

let posiage: Int? = ages["granddaughter"]
if posiage == nil {
	print("age not found.")
}
//合并上面两段的写法
if let age =ages["mom"]{
	print("an age of \(age) was found. ")
}

if和switch

var age = 32
if age == 1 {
    print("happy first birthday")
}else if age == 40 {
    print("happy 40th birthday")
}else {
    print("happy plain old boring birthday")
}

age = 50
switch age{
case 1:
    print("happy first birthday")
case 13...19:
    print("happy birthday, teenager!")
case let decade where decade % 10 == 0:
print("happy significant \(decade)th birthday")
default:
    print("happy plain old boring birthday")
}

let user = "bod"
let passvalid = true
switch (user, passvalid){ //元组 turple
case ("admin", true):
    print("welcome back, administrator")
case("guest", _): //忽略密码项
    print("guests are not allowed in this restricted area.")
case(_, let isvald): //第二个项目passvalid声明为常量.
    print(isvald ? "welcome: \(user)" : "access denied")
}

注意:

  1. 运算符左右两端的空格是必须的.
  2. 变量和常量小写开头.
  3. 类型比如Int String都是大写开头.

第二段 function & closure - 函数和闭包

函数的参数

//参数
func sendMessage(_ message: String, to recipient: String, shouting: Bool = false){
    var message = "\(message), \(recipient)!"
    if shouting{
        message = message.uppercased()
    }
    print(message)
}

sendMessage("see you at the bash", to: "morgan")

建议todo wwdc2016 swift api design guidelines

函数的返回值

func firStr(havingpre pre:String, in strs:[String])-> String?{
    for stri in strs{
        if stri.hasPrefix(pre){ //参数中的pre
            return stri
        }
    }
    return nil
}

var guests=["dad", "mom", "sister", "daughter"]
if let gue=firStr(havingpre:"d", in: guests){
    print("see you at the party. \(gue)~!")
}else {
    print("invite must be in the mail")
}

函数的基础形式

//函数的基础形式 function types
(parameter types) -> return type
func firStr(havingpre pre:String, in strs:[String])-> String?{
(string, [string]) -> string?

函数作为参数

func filterint(_ numbers: [Int], _ includenum:(Int) -> Bool) -> [Int]{
    var res :[Int]=[]
    for num in numbers{
        if includenum(num){
            res.append(num)
        }
    }
    return res   
}
let nums = [4, 17, 34, 41, 82]
func divis2(_ num: Int) -> Bool{
    return num % 2 == 0
}
let evens = filterint(nums, divis2)
print(evens)

closure闭包没有函数名

let evens = filterint(nums, 
	{(num: Int) -> Bool in return num % 2 == 0 } //参数lable可以省略这个就不需要了
)
	{num in return num % 2 == 0 } //参数和返回值类型都可以推断出来.
	{num in num % 2 == 0 } //一定return, 因此return不需要.
	{$0 % 2 == 0 } //参数名也是不需要的, $0就是第一个参数
	
let even2 = filterint(nums)
	{$0 % 2 == 0 } //如果闭包closures是最后一个参数, 那么可以放在小括号后面.

generic 泛型

func filter<element>(_ source: [element], _ includele:(element) -> Bool) -> [element]{
    var res :[element]=[]
    for ele in source{
        if includele(ele){
            res.append(ele)
        }
    }
    return res
}
let nums = [4, 17, 34, 41, 82]
var names=["dad", "mom", "sister", "daughter"]
let even2 = filter(nums){$0 % 2 == 0 }
let shortname = filter(names){name in name.characters.count < 5 }

// 任何的集合都有filter和map这两个泛型函数
names.filter{name in name.characters.count < 5 }
// 连点方式
let capitalshort = names
.filter{name in name.characters.count < 5 }
.map{name in name.uppercased()}

print(capitalshort)

自定义类型 custom types

struct 结构组织体系

struct rectangle{
    var width = 12 //property 属性
    var height = 24
}
var rec = rectangle()
rec.height = 4
///参数化
struct rectangle2{
    var width : Int
    var height : Int
    // 可计算属性 computer property
    var area: Int{
        return width * height
    }
}
var rec2 = rectangle2(width: 4, height: 5)

方法method

//method 方法
struct rectangle3{
    var width : Int
    var height : Int
    // 可计算属性 computer property
    var area: Int{
        return width * height
    }    
    func fitin(_ other: rectangle3) -> Bool{  //自定义方法method
        return (width < other.width) && (height < other.height)
    }
}

let small = rectangle3(width: 4, height: 5)
let large = rectangle3(width: 14, height: 15)
small.fitin(large)

自定义初始化init

//一般而言, 系统默认的初始化函数就够用了, 可以初始化所有属性property, 不必初始化计算属性computered property.
struct rectangle4{
    var width : Int
    var height : Int
    // 可计算属性 computer property 这个特别关键, 其实是另外一种method
    var area: Int{
        return width * height
    }    
    func fitin(_ other: rectangle3) -> Bool{  //自定义方法method
        return (width < other.width) && (height < other.height)
    }
   init(width: Int, height: Int){ //这个初始化函数特殊, 不需要func关键字.
   		self.width  = width
   		self.height = height     
   } 
}

对自定义类型的扩展

//定义好的类型也是可以继续扩展的, 可以扩展计算属性(computed property)或者方法(method)
//但是, 不能扩展普通需要存储的属性(stored property), 比如那些需要init初始化的属性就不行.  
struct rectangle5{
    var width : Int //类似这样的属性必须写在这个核心声明里面, core functionality
    var height : Int
}
extension rectangle5 {
 // 可计算属性 computer property
 var area: Int{
    return width * height
 }
 func fitin(_ other: rectangle5) -> Bool{  //自定义方法method
    return (width < other.width) && (height < other.height)
 }
 var width3 : Int // 这句话会报错, 这种stored property不能扩展.
}

泛型类型 generic types

//generic types 泛型类型
struct namearray<ele>{
    var name: String
    var items : [ele]
}

let games: namearray<String> = namearray(name: "board game", items: ["chess", "go"])
let primes: namearray<Int> = namearray(name: "primes", items: [1, 3, 5, 7, 13]) // 素数集合

let games2 = namearray(name: "board game", items: ["chess", "go"])
let primes2 = namearray(name: "primes", items: [1, 3, 5, 7, 13]) // 素数集合
print(games2)

class 类

  1. class和struct 都一样.
  2. class的实例是传引用的. struct是传值的.
  3. class可以有儿子
class fish {
  func swim(){ //神奇了, 这个括号又是不可省略的了.
    print("i am swiming")
  }
}
class flyfish: fish{ // 子类扩展了新的方法method
  func fly(){
    print("flying thought the air!") // through & thought 两个意思了. 呵呵, 有趣
  }
}
class complainfish: fish{
  override func swim(){ //重载了父类的方法
    print("grumble, grumble, grumble...")
    super.swim()
  }
}

protocol条约/协议/草案

protocal fish {
  func swim() //不必实现
}
class flyfish: fish{ // 子类扩展了新的方法method
   func swim(){ //不需要override关键字
    print("air, water, air, water...")
  }
}
struct complainfish: fish{ // 用结构也行
   func swim(){ 
    print("grumble, grumble, grumble...")
  }
}

实战, 改变一个类型的描述字符串

  1. swift的所有类型都可以转化为字符串, 因为默认就会有协议可以打印出任何的类型不论是struct还是class还是基础类型.
  2. 如果要定制化一个类型的字符串输出, 就要用一个协议customstringconvertible
//原本的协议的声明
protocol CustomStringConvertible{
    var description: String{get}
}
//我们可以在自己的类里面扩展这个声明
extension flyfish: CustomStringConvertible{
    var description: String{
        return "oeuoeuoaeueouoeueoueoaueouoeuoaeu"
    }
}

建议去看todo:

  1. wwdc2015 protocol-oriented program
  2. wwdc2016 protocol and value oriented programming in uikit apps

enumerations列表

enum align{
  case left
  case right
}
enum align{ //更简略的写法
  case left , right
}
let tex=align.left
switch tex{
case align.left: print("lean to the left")
case align.right: print("lean to the right")
}
// 可以省略enum的名字align
switch tex{
case .left: print("lean to the left")
case .right: print("lean to the right")
}

enum的项目还可以关联值

enum align{ 
    case left(padding: Double) , right(padding: Double)
}
let tex=align.left(padding: 40.7)

switch tex{
case .left(let pad): print("lean to \(pad)the left")
case .right: print("lean to the right")
}

还可以指定enum项目的类型

enum align: String{ 
  case left = "leleelelelel" 
  case right = "ririririri"
} //这个也是可以把字符串集中起来, 实话说, 这不是啥好主意.
//enum可以作为参数, 声明在函数声明.
func xxx(from server: align){} 
//传参数就可以直接用enum的项了. 比如
xxx(from: .left)

异常和报错

略过了 目前没看到用处.

地址: https://developer.apple.com/wwdc16/404

实际: https://developer.apple.com/videos/play/wwdc2016/404/

这个下面的三个tab里面有需要的一切, 比如相关视频

What’s New in Swift
Swift API Design Guidelines
What’s New in Foundation for Swift
Introducing Swift Playgrounds
Going Server-Side with Swift Open Source
Protocol and Value Oriented Programming in UIKit Apps

Swift Get-Together
Swift Open Hours
Swift Open Hours