Swift 3學習筆記第一篇(語法概覽)

Deft_MKJing宓珂璟發表於2017-04-13

1.簡單值

let 宣告常量,var 宣告變數,在變數名後面跟上:型別 來顯示宣告,不跟的話編譯器會根據型別自動做出型別判斷
這裡寫圖片描述

/*
 * 1.宣告
 */
//: 隱身宣告
let interNum = 50

//: 顯示宣告
let expliceNum :Double = 40

2.字串拼接

String() 可以顯示轉換`,或者用反斜槓+()來表示佔位符,進行字串轉換

/*
 * 2.字串拼接
 */
//:1. 字串拼接(數字轉字串)
let lable = "mmikejing"

let width = 30

let lableWidth = lable + String(width)
print(lable + "\(width)")

//:2.字串拼接(\())
let xiaoming = 10
let xiaohong = 20
let sumAge = "all ages is \(xiaoming + xiaohong)"

let xiaohei :Double = 99.1
let sumLeave = "xiaohei de age \(xiaohei)"


3.字典和陣列建立訪問

字典和陣列都是用[] 進行包裝,字典裡面是鍵值對,[key:value] 陣列裡面是單個值[value],其中空陣列的型別宣告可以是[]Array<Int>,值得注意的是字典的宣告時[:]Dictionry<String,Int>,後面是逗號隔開,而不是冒號了

//: 1.陣列
var shoppingList = ["ta","he","she","her","we"]
print(shoppingList[1])
shoppingList[1] = "666"
print(shoppingList)


//: 2.字典
var dic :Dictionary = ["JSON":20,"LUSIA":30]
print(dic["JSON"]!) // 不加!是optional(20),強行拆包
dic["MKJ"] = 100
print(dic);

//: 3.空陣列和空字典的建立
let emptyArray = [String]()  // 型別 + ()
var emptyArray1 = Array<Int>() // 型別 + ()
var emptyArray2:Array<Int> = [] // 顯示宣告 + 直接[]初始化


let empryDict = [String:Float]() // 型別 + ()
let empryDict1 = Dictionary<String,Float>() // 字典(,分割) + ()
let emtpryDict2:Dictionary<String,Float> = [:]


4.控制流 if else for-in

1.if-else中判斷語句一定要是個表示式,不能像OC一樣直接寫一個例如,if(entity)上去,swift中不支援隱式轉換
2.switch可以是任何型別
3.for-in中..< 不包含右區間,... 包含右區間

/*
 * 4.控制流 if switch for-in  while  do while
 */

//: 示例 1   if else
let scroes = [10,50,80,98,17]
var teamScroes = 0
for score in scroes {
    if score > 50 { // ---> if語句中必須是一個bool表示式  不能直接寫score,系統不會進行預設的和0判斷
        print(score)
        teamScroes += 3
    }
    else
    {
        teamScroes += 1
    }
}
print(teamScroes)


//: 示例 2  let常量的nil判斷
var optionStr :String? = "woshiyizhizhu"
print(optionStr == nil)

// requires a contextual type
// let hehe = nil  
// let宣告的變數不能為nil,因此可以拿這個點來做if判斷,因為swift不可以直接把值弄上去,系統不會自動和0進行比對,一定要給表示式

var optionalStr : String? = "mikejing"
var greeting = "Hello!"
if let name = optionalStr {
    greeting = greeting + optionalStr!
}
else
{
    greeting = greeting + "chengjinjiao"
}
print(greeting)


//: 示例 3 switch支援任意型別的資料以及各種比較操作——不僅僅是整數以及測試相等。
// 宣告'let'可用於匹配某部分固定值的模式 這句話有待琢磨。。。
let vagetable = "red tiger"
var vagetaleComment = ""
switch vagetable {
case "hehe":
    vagetaleComment = "add some numb"
case "wuyu":
    vagetaleComment = "that is a pig"
case let x where x.hasPrefix("red"):
    vagetaleComment = "yes get it \(x)"
default:
    vagetaleComment = "done"
}
print(vagetaleComment)

//: 示例 4 for in字典  查詢最大值以及對應的key
let interestingNums = ["Prime":[1,2,3,4,5,6,7,40],"Fibonacci":[1,1,2,3,5,8],"Squre":[1,4,9,16,25,36]]
var largest = 0
var largestKey :String? = nil
for (key,value) in interestingNums {
    for num in value {
        if num > largest {
            largest = num
            largestKey = key
        }
    }
}
//print(largestKey! + " + " + String(largest))
print(largestKey! + "+" + "\(largest)")

//: 示例 5 簡單的迴圈使用
// ..<不包含最大   ...包含最大值
var firstForLoop = 0
for i in 0..<4 {
    firstForLoop += i
}
print(firstForLoop)


5.函式

語法:(argv:型別,argv:型別)->(型別)

/*
 * 5.函式
 */
//: 示例1 基本函式
func greet(name:String,today:String,food:String) -> String{
    return "Hello \(name) today is \(today) eat \(food) im very happy"
}

print(greet(name: "MKJ", today: "4月10日", food: "��肉乾"))



//: 示例2 利用元祖返回多個值
// 引數的值對應的寫法的兩種不同表現形式
// 例如是陣列  1.scroes:[Int]  2.scroes:Array<Int>
// 例如是字典 1.scroes:[String:Int]  2.Dictionary<String,Int> 注意字典這裡用的是逗號,不是冒號
func calculateStatics(scroes:Array<Int>) -> (min:Int , max:Int ,sum:Int)
{
    var min = scroes[0]
    var max = scroes[0]
    var sum = 0
    for sc in scroes {
        if sc > max {
            max = sc
        }
        else if sc < min {
            min = sc
        }
        sum += sc
    }
    return(min,max,sum)
}
let result = calculateStatics(scroes: [1,3,5,45,4])
print("max--->\(result.max),min--->\(result.min),sum--->\(result.sum)" + "--->mikekeing")


6.閉包

1.定義:函式可以被巢狀,被巢狀的函式可以訪問外側函式的變數
2.函式作為返回值() -> ((Int) -> Int) 這裡注意的是,3以後引數要加括號,之前貌似不需要加括號

/*
 * 5.閉包  
 * 函式可以被巢狀,被巢狀的函式可以訪問外側函式的變數
 */
//: 示例1 最簡單的閉包 函式巢狀
func closure_func () -> Int{
    var x = 0
    func add(){
        x += 10
    }
    add()
    return x
}
print("\(closure_func())")


//: 示例2 函式作為返回值  注意這裡需要用函式作為返回值的時候引數一定要用括號,swift2.3的時候貌似不需要多好都行
//: error ---> single argument function types require parentheses
func makeImprove() -> ((Int) -> Int)
{
    func addCount(number:Int) -> Int{
        return number + 2
    }
    return addCount
}

var method = makeImprove()
print("\(method(10))")


//: 示例3 函式作為引數
func hasAnyMatch(list:Array<Int>,condition: (Int) -> Bool) -> Bool
{
    for score in list {
        if condition(score) {
            return true
        }
    }
    return false
}


func largeThan(number:Int) -> Bool
{
    return number > 100
}

var counts = [54,53,67,37,9,75]

print("是否有值大於100--->\(hasAnyMatch(list: counts, condition: largeThan))")

/*
 * 注意:1.閉包就是函式內嵌,內部函式可以訪問其外部變數
 *      2.函式作為引數或者作為返回值,表達函式指標的時候一定要把引數型別加上括號,不然就error
 */



閉包的語法以及縮寫
1.用{} 來建立閉包
2.內部用in 進行函式宣告和函式體的分離{(引數)->(返回值) in 函式體}
3.用$0,$1 來進行函式引數和返回值的和in的省略,直接呼叫$0函式體 來進行閉包的實現

//: 示例4 函式其實就是一個特殊的閉包,使用{}來建立一個閉包,然後使用in 來分離引數返回值和函式體
let testResult = counts.map { (number:Int) -> Int in
    let result =  3 * number
    return result;
}
print(testResult)

// 示例5 匿名函式體的建立和使用例子 使用$0  $1來省略引數型別返回值和in,保留函式體
let cast = ["Vibim","John","Kibui","Koikis","YiYOLLLLLL"]
let lowcaseNames = cast.map {$0.lowercased()}
print(lowcaseNames)
let lowcaseCount = cast.map {$0.characters.count}
print(lowcaseCount)


// 示例6 正常和縮寫的對比
let sortNumber = [1,55,6,3,75,43,73,4,64,66]
let sortedNum = sortNumber.sorted { (a, b) -> Bool in
    return a < b
}
print(sortedNum)


let sortenNum1 = sortedNum.sorted {$0 > $1}
print(sortenNum1)


// 示例7 重寫閉包 對所有的奇數返回0
func testOdd(list:[Int]) -> [Int]
{
    var oddList = Array<Int>()
    func isOdd(num:Int) -> (){
        oddList.append(num % 2 == 0 ? num : 0)
    }
    for value in list {
        isOdd(num: value)
    }
    return oddList
}
print(testOdd(list: sortNumber))


7.類與物件的建立

通過class 類名 : 父類名,協議 的語法宣告,內部可以有屬性,方法,值得注意的時候get和set方法的寫法

// 類與物件的建立
// 形狀基礎類
class BaseShape {
    // 可以宣告的時候初始化
    var numberOfSide:Int = 0
    var name:String
    init(name:String) {
        // 也可以析構的時候設定
        self.name = name
    }
    func baseDescription() -> String {
        return "a shape with \(numberOfSide) sides."
    }
}
var shape = BaseShape(name:"base shape")
shape.numberOfSide = 100
print(shape.baseDescription())

// 正方形
class Square : BaseShape{
    var sideLength:Double
    init(sideL:Double,name:String) {
        self.sideLength = sideL
        super.init(name: name)
        numberOfSide = 4
    }
    func areaSquare() -> Double {
        return sideLength * sideLength
    }
    override func baseDescription() -> String {
        return "square shpe with \(self.numberOfSide) sides."
    }
}

var squareShape = Square(sideL:8.8,name:"正方形")
print(squareShape.name + "area-->\(squareShape.areaSquare())  "+squareShape.baseDescription())

// 圓形
class Circle : BaseShape{
    var radi :Double
    init(radi:Double,name:String) {
        self.radi = radi
        super.init(name: name)
        self.numberOfSide = 1000
    }

    func areaCircle() -> Double {
        return 2 * 3.14 * radi * radi
    }

    var perimeter:Double{
        get{
            return 2 * 3.14 * radi * radi
        }
        set{
            self.radi = newValue
        }
    }

    override func baseDescription() -> String {
        return "Circle shpe with \(self.numberOfSide) sides."
    }

}

var circleShape = Circle(radi:5,name:"圓")
print(circleShape.name + "area-->\(circleShape.areaCircle())  "+circleShape.baseDescription())
circleShape.perimeter = 10.0
print(circleShape.name + "area-->\(circleShape.perimeter)  "+circleShape.baseDescription())


8. 列舉

// 列舉
enum Rank:Int{
    case Ace = 1
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack,Queen,Kink
    func comparision(a:Rank) -> Bool {
        return self.rawValue > a.rawValue
    }

    func descriptionSimple() -> String {
        switch self {
        case .Ace,.Two, .Three, .Four, .Five, .Six, .Seven, .Eight, .Nine, .Ten:
            return "ACE"
        case .Jack:
            return "JACK"
        case .Queen:
            return "QUEUE"
        case .Kink:
            return "KINK"
        default:
            return String(self.rawValue)
        }
    }
}

print("左值大於右值?--->\(Rank.Jack.comparision(a: Rank.Six))   " + Rank.Four.descriptionSimple())
Rank.Queen.rawValue // 正向裝換
Rank(rawValue:12)?.descriptionSimple() // 逆向轉換


// 列舉無非就是指定一個值 一個引用針對某一個值  元祖的引數方式有所不同
enum ServerResponse {
    case Result(String, String)
    case Error(String)
}
// 建立第一個
let success = ServerResponse.Result("6:00 am", "8:09 pm")
// 建立第二個
let failure = ServerResponse.Error("Out of cheese.")

switch success {
case let .Result(sunrise, sunset):
    let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)."
case let .Error(error):
    let serverResponse = "Failure...  \(error)"
}


9.協議和擴充套件

// 定義
protocol SomeProtocol {
// 這裡是協議的定義部分
}
// 建立
struct SomeStructure: FirstProtocol, AnotherProtocol {
// 這裡是結構體的定義部分
}

// 擁有父類的寫法
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 這裡是類的定義部分
}
它只指定屬性的名稱和型別。此外,協議還指定屬性是隻讀的還是可讀可寫的。
協議通常用 var 關鍵字來宣告變數屬性,在型別宣告後加上 { set get } 來表示屬性是可讀可寫的,只讀屬性則用 { get } 來表示

// 協議的方法要求 不需要大括號和方法體。
protocol RandomNumberGenerator {
func random() -> Double
}


看最簡單的示例

protocol sampleProtocol{
    // 任何sampleProtocol型別都得有一個只讀的protocolProperty屬性,型別為String 不能通過setter進行設值,只getter進行取值 計算型別
    var protocolProperty:String {get}
    // 結構體和列舉是值型別。預設情況下,值型別的屬性不能在它的例項方法中被修改  mutating
    // 實現協議中的 mutating 方法時,若是類型別,則不用寫 mutating 關鍵字。而對於結構體和列舉,則必須寫 mutating 關鍵字  修改值型別關鍵字
    mutating func appending()
}

class ExampleEntity : sampleProtocol{
    var protocolProperty: String = "mikejing  "
    // 類是物件屬性,有地址,因此可以在方法中直接進行值的修改
    func appending() {
        protocolProperty += "class option protocol"
    }
}
var entityE = ExampleEntity()
entityE.appending()
print(entityE.protocolProperty)

// struct和enum都是值型別,不能在方法中進行屬性值得修改,如果需要修改,必須加上mutating關鍵字
struct StructValue : sampleProtocol{
    var protocolProperty :String = "chengjingjiao  "
    mutating func appending() {
        protocolProperty += "struct option protocol"
    }
}

var structE = StructValue()
structE.appending()
print(structE.protocolProperty)

// 擴充套件方法 擴充套件int型別,自增一倍
extension Int : sampleProtocol{
    var protocolProperty: String{
        return "the number \(self)"
    }
    mutating func appending() {
        self += self
    }
}
var intNum = 200
intNum.appending()

extension String {
    var banana : String {
        let shortName = String(characters.dropFirst())
        return "\(self) \(self) you are bitch \(shortName)"
    }
}

let bananaName = "Jimmy".banana





筆記地址,每週更新一點
這裡寫圖片描述

相關文章