swift 3.0

作者: MRNAN_ | 来源:发表于2016-10-18 15:10 被阅读337次

    导入格式

    import UIKit // 在OC 中的导入格式是:#import<UIkit/UIKit.h>,swift相比于OC更加简洁

    基础部分

    一、常量和变量

    在swift中使用var表示变量,let表示常量

    “Swift 包含了 C 和 Objective-C 上所有基础数据类型,Int表示“整型值; Double 和 Float 表示浮点型值; Bool 是布尔型值;String 是文本型数据。 Swift 还提供了三个基本的集合类型,Array ,Set 和 Dictionary ,详见集合类型”

    #常量

    // 指定常量的类型
    let isSuccess:Bool = true
    let aString :String = "i`m a string 🐶"
    let aInt :Int = 666
    // 不指定常量类型,编译器自动去判断
    let 🐶 = "i`m a dog"
    let bInt = 888
    ** 常量的值不可以去修改 **
    

    运行结果

    Paste_Image.png Paste_Image.png

    #变量

    // 变量
    //指定变量类型
    var bString :String
    bString = aString
    var cInt:Int
    cInt = bInt
    
    // 不指定类型
    var dInt = bInt
    
    //修改值
    dInt = 0000
    bString = "it`s can change"
    

    运行结果

    Paste_Image.png

    二、数值类型转换

    // 整数和浮点型转换
    let three = 3  // 3
    let doubleNumber = 0.1415926   // 0.1415926
    let pi = Double(three)+doubleNumber  // 3.1415926
    // 浮点数到整数的反转换
    let intPi = Int(pi) // 3
    

    三、类型别名

    “类型别名(type aliases)就是给现有类型定义另一个名字。你可以使用typealias关键字来定义类型别名。”

    typealias MyStr = String
    let Str:MyStr = "我是字符串"   //  "我是字符串"
    

    四、元组

    “元组(tuples)把多个值组合成一个复合值。元组内的值可以是任意类型,并不要求是相同类型。”
    下面这个例子中,(404, "Not Found") 是一个描述 HTTP 状态码(HTTP status code)的元组。HTTP 状态码是当你请求网页的时候 web 服务器返回的一个特殊值。如果你请求的网页不存在就会返回一个 404 Not Found 状态码。

    let http404Error = (404, "Not Found")
    // http404Error 的类型是 (Int, String),值是 (404, "Not Found")”
    

    **#元组的取值方式 **
    元组的取值方式主要有三种:
    1.通过内容分解
    2.通过下标
    3.通过元素别名

    // 1.通过内容分解来取值
    let (errorCode,message) = http404Error
    print("errorCode is \(errorCode)")     // "errorCode is 404"
    print("message is \(message)")        // "message is Not Found"
    // 如果只需要一个值得话,可以把要忽略的部分用下划线_标记
    let (errorCode1,_) = http404Error   // "404"
    print(errorCode1)
    
    // 2.通过下标来取值
    let httpCode = http404Error.0  // 404
    
    //3.通过元素的别名来取值
    //先给元素起个别名
    let http404ErrorName = (errorCode:404,message:"Not Found")
    let errorMessage = http404ErrorName.message  // "Not Found"
    

    五、可选类型(optionals)

    *** 在OC中我们定义一个暂时不用的变量的时候可以这样:Int a ,NSString str = nil.但是在swift中不允许这样,因为swift是强类型语言,nil在swift中也是一种类型,类型不一样是不可以赋值的,所以推出了一种可选类型,在swift中规定:在创建对象时,对象中的任何属性都必须要有一个明确的初始化值** *

    Swift 的 Int 类型有一种构造器,作用是将一个 String 值转换成一个 Int 值。然而,并不是所有的字符串都可以转换成一个整数。字符串 "123" 可以被转换成数字 123 ,但是字符串 "hello, world" 不行。

    “let possibleNumber = "123"
    let convertedNumber = Int(possibleNumber)
    // convertedNumber 被推测为类型 "Int?", 或者类型 "optional Int”
    

    因为该构造器可能会失败,所以它返回一个可选类型(optional)Int,而不是一个 Int。一个可选的 Int 被写作 Int? 而不是 Int。问号暗示包含的值是可选类型,也就是说可能包含 Int 值也可能不包含值。(不能包含其他任何值比如 Bool 值或者 String 值。只能是 Int 或者什么都没有。)

    // 你可以给可选变量赋值为nil来表示它没有值:
    serverResponseCode = nil
    // serverResponseCode 现在不包含值”
    

    ** # if语句和强制解析 **
    你可以使用 if 语句和 nil 比较来判断一个可选值是否包含值。你可以使用“相等”(==)或“不等”(!=)来执行比较。

    如果可选类型有值,它将不等于 nil:

    if convertedNumber != nil {
        print("convertedNumber contains some integer value.")
    }
    // 输出 "convertedNumber contains some integer value.
    

    确定可选类型确实包含值之后,你可以在可选的名字后面加一个感叹号(!)来获取值。这个惊叹号表示“我知道这个可选有值,请使用它。”这被称为可选值的强制解析

    if convertedNumber != nil {
        print("convertedNumber has an integer value of \(convertedNumber!).")
    }
    // 输出 "convertedNumber has an integer value of 123.
    

    # 可选绑定
    *** 使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋给一个临时常量或者变量。可选绑定可以用在 if 和 while 语句中,这条语句不仅可以用来判断可选类型中是否有值,同时可以将可选类型中的值赋给一个常量或者变量 ** *

    if let actualNumber = Int(possibleNumber) {
        print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
    } else {
        print("\'\(possibleNumber)\' could not be converted to an integer")
    }
    // 输出 "'123' has an integer value of 123
    
    这里面其实进行了两步操作:1.先判断possibleNumber 是不是nil,是的话就不执行大括号里的语句。2.不空的话对possibleNumber 进行解包赋值 .但是这种的话每次都得起一个别名
    

    ** # ??(空合运算符)**
    **空合运算符(a ?? b)将对可选类型 a 进行空判断,如果 a 包含一个值就进行解封,否则就返回一个默认值 b。表达式 a 必须是 Optional 类型。默认值 b 的类型必须要和 a 存储值的类型保持一致。 **

    let nickName :String? = nil
    let fullName :String = "Harry"
    // 如果可选值nickName是nil的话可以使用默认值来代替.??用来提供一个默认值
    let inforGrreting = (nickName ?? fullName)
    

    字符串和字符(字符串是值类型)

    1.初始化
    初始化有两种方式

    //1.使用初始化方法初始化
    var anotherEmptyString = String()   
    //2. 使用字符串常量初始化 
    var str = "Hello, playground"
    var str0 = ""   //初始化一个空字符串  
    

    可以通过检查其Bool类型的isEmpty属性来判断该字符串是否为空:

    if emptyString.isEmpty {
        print("Nothing to see here")
    }
    // 打印输出:"Nothing to see here
    

    2.字符串的操作(增删改)

    // 1.字符串拼接
    var s = "我是原始的"   // "我是原始的"
    let s0 = s + "\n 我是通过+追加的字符串" // "我是原始的\n 我是通过+追加的字符串"
    s += s0  //通过赋值运算符(+=)将一个字符串添加到一个已经存在字符串变量上
    s.append("\n 我是append拼接的字符串")  // "我是原始的我是原始的\n 我是通过+追加的字符串\n 我是append拼接的字符串"
    // 2. 计算字符数量
    // 如果想要获得一个字符串中 Character 值的数量,可以使用字符串的 characters 属性的 count 属性
    
    // 3. 访问和修改字符串
    // 关键字 string.Index ,对应着字符串中的每一个character 的位置
    // 使用 startIndex 属性可以获取一个 String 的第一个 Character 的索引。使用 endIndex 属性可以获取最后一个 C haracter 的后一个位置的索引。因此, endIndex 属性不能作为一个字符串的有效下标。如果 String 是空串, artIndex 和 endIndex 是相等的
    let sss = "hello world"    // "hello world"
    // .endIndex.predecessor ,获取最后一个字符,swift3中用的是index(befor:)
    sss[sss.startIndex]  // "h"
    sss[sss.index(after: sss.startIndex)]   //  "e"
    sss[sss.index(before: sss.endIndex)]  // "d"
    // 通过下标语法获取
    let index = sss.index(sss.startIndex, offsetBy: 7)   // 7
    let indexStr = sss[index]  // "o"
    
    // 截取字符串
    var  strNum = "12>345</6"
    //let startIndex = strNum.range(of: ">")?.lowerBound
    //let startIndex0 = strNum.characters.index(of: ">")
    //let endIndex0 = strNum.characters.index(of: "<")
    //// “endIndex属性可以获取最后一个Character的后一个位置的索引”,这里是upperBound
    //let end = strNum.range(of: "</")?.upperBound
    //let endIndex = strNum.index(before: end!)
    //
    //let range = Range(uncheckedBounds: (startIndex0!,endIndex))
    //let newS = strNum.substring(with: range)
    
    let startIndex = strNum.range(of: ">")?.upperBound
    let endIndex = strNum.range(of: "</")?.lowerBound
    let range = Range(uncheckedBounds: (startIndex!,endIndex!))
    let newS = strNum.substring(with: range)
    
    
    // 插入和删除
    // 调用 insert(_:atIndex:) 方法可以在一个字符串的指定索引插入一个字符,调用 insert(contentsOf:at:) 方法可以在一个字符串的指定索引插入一个段字符串
    var welcome = "hello"
    welcome.insert("!", at: welcome.endIndex)
    // welcome 变量现在等于 "hello!"
     
    // 调用 remove(at:) 方法可以在一个字符串的指定索引删除一个字符,调用 removeSubrange(_:) 方法可以在一个字符串的指定索引删除一个子字符串。
    
    “welcome.remove(at: welcome.index(before: welcome.endIndex))
    // welcome 现在等于 "hello there"
     
    let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
    welcome.removeSubrange(range)
    // welcome 现在等于 "hello”
    
    welcome.insert(contentsOf:" there".characters, at: welcome.index(before: welcome.endIndex))
    // welcome 变量现在等于 "hello there!
    
    // 4 . 遍历字符串
    for character in label.characters
    {
        print(character)
    }
    
    // 5.字符串插值
    let multiplier = 3
    let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
    // message is "3 times 2.5 is 7.5"
    * multiplier作为\(multiplier)被插入到一个字符串常量量中。 当创建字符串执行插值计算时此占位符会被替换为multiplier实际的值 *
    
    // 6. 比较字符串
    // 字符串/字符可以用等于操作符(==)和不等于操作符(!=)
    let quotation = "We're a lot alike, you and I."
    let sameQuotation = "We're a lot alike, you and I."
    if quotation == sameQuotation {
        print("These two strings are considered equal")
    }
    // 打印输出 "These two strings are considered equal
    

    集合类型

    ** * Swift 语言提供Arrays、Sets和Dictionaries三种基本的集合类型用来存储集合数据。数组(Arrays)是有序数据的集。集合(Sets)是无序无重复数据的集。字典(Dictionaries)是无序的键值对的集。** *

    一、数组

    1.初始化方法

    // 声明数组的方式常用的是下面两种
    //1. 声明一个不可变数组
    let array = ["hhh","xixiix","gagaga"]
    //2.声明一个空的可变数组 ,用初始化方法
    var arrayM = [String]()  // 或者 var arrayM = Array <String>() 这种写法看着很麻烦,不常用
    

    2.可变数组的基本操作(增删改)

    //1. 添加元素
    arrayM.append("wawo")
    arrayM.append("nihao")
    arrayM.append("hello")
    //2. 删除元素
    arrayM.remove(at: 0)
    print(arrayM)
    //3. 取出元素并附新值
    
    arrayM[0] = "very good"
    //4. 遍历数组
    //4.1 通过下标来遍历
    for i in 0..<array.count
    {
        print(array[i])
    }
    //4.2 直接遍历
    for str in array
    {
        print(str)
    }
    // 4.3 只遍历前两个元素
    for name in array[0..<2]
    {
        print(name)
    }
    //5. 数组合并
    let addArray = arrayM + array  // 只有相同类型的数组可以相加
    

    二、字典

    1.初始化

    var dict = ["name":"hello","age":20] as [String : Any];
    print(dict["age"])
    // 创建一个新的字典,用初始化方法
    var myDictionary = [String:Any]()
    

    2.可变字典的操作

    //6.1.1添加元素
    myDictionary["name"] = "petter"
    myDictionary["weight"] = 60
    myDictionary["height"] = 1.88
    myDictionary
    //6.1.2删除元素
    myDictionary.removeValue(forKey: "weight")
    myDictionary
    //6.1.3获取元素,修改元素
    myDictionary["name"] = "Job"
    //如果字典里面没有对应的key会在字典里新添加一对键值对
    myDictionary["sex"] = "male"
    myDictionary
    //6.1.4遍历字典
    //遍历所有的key
    for key in myDictionary.keys
    {
        
    }
    //遍历所有的value
    for value in myDictionary.values
    {
        
    }
    //遍历所有的键值对
    for (key,value) in myDictionary
    {
        
    }
    //5.1.5合并  字典即使类型一致也不能进行相加合并
    var dict1 = ["name":"peter","age":20] as [String:Any]
    let dict2 = ["sex":"male","height":188] as [String:Any]
    
    for (key,value) in dict2
    {
        dict1[key] = value
    }
    dict1
    

    控制流

    ** * Swift提供了多种流程控制结构,包括可以多次执行任务的while循环,基于特定条件选择执行不同代码分支的if、guard和switch语句,还有控制流程跳转到其他代码位置的break和continue语句。还提供了for-in循环,用来更简单地遍历数组(array),字典(dictionary),区间(range),字符串(string)和其他序列类型。 ***

    1.for in 循环

    let interestingNumbers = [
        "one":[1,2,3,4],
        "two":[0,-1,5],
        "three":[9,10,4,29]
    ];
    var largest = 0
    for(kind,numbers) in interestingNumbers
    {
        for number in numbers    // swift 的for in 不加括号
        {
            if(number > largest)
            {
                largest = number
            }
        }
    }
    print(largest)
    

    2.While 循环
    Swift 提供两种while循环形式:

    ****while循环,每次在循环开始时计算条件是否符合;***
    ****repeat-while循环,每次在循环结束时计算条件是否符合。***

    var num = 1
    while num < 3
    {
        num = num * 2
    }
    print(num)   // 打印结果  : 4
    
    // do while(swift中将do 改成了 repeat) 循环放在结尾保证循环至少被执行一次
    var n = 1
    repeat {
        n = n * 2
    }while n < 3
    print(n)  // 打印结果: 4
    

    ** 3.switch **

    // switch 语句 ,最基本的用法
    let color = "red color"
    switch color{
        case "blue":
        print("the color is blue")
        case "white":
        print("the coloe is white")
        // 这个会将后缀含有color 的结果赋给x
        case let x where x.hasSuffix("color"):
            print("the color is \(x)")
        default:
            print("no color")
    }
    

    ** #匹配区间**

    Paste_Image.png
    // switch 也可以使用元组
    // 比如 一个坐标系中的点,X轴是-2到2,Y轴也是-2到2,判断某个点(x,y),使用(Int,Int)类型的元组
    let somePoint = (1,1)
    switch somePoint {
    case (0,0):
        print("is a origin point")
    case (_,0): // “使用下划线(_)来匹配所有可能的值”
        print("\(somePoint.0) 在X 轴上")
    case (0,_):
        print("(\0,\(somePoint.1)) 在Y轴上")
    case (-2...2,-2...2):
        print("(\(somePoint.0),\(somePoint.1) 在这个坐标系里面)")
    default:
        print("不在当前坐标系范围内")
    }
    
    // case语句可以用where语句来判断额外的条件
    let AnotherPoint = (-1,1)
    switch AnotherPoint {
    case let(x,y) where x == y:
        print("x= y")
    case let(x,y) where x == -y:
        print("x==-y")
    case let(x,y):  // 这里用的是值绑定,“case 分支的模式允许将匹配的值绑定到一个临时的常量或变量,这些常量或变量在该 case 分支里就可以被引用了” “这三个 case 都声明了常量x和y的占位符,用于临时获取元组anotherPoint的一个或两个值” “case let(x, y)声明了一个可以匹配余下所有值的元组。这使得switch语句已经完备了,因此不需要再书写默认分支。”
        print("the point is (\(AnotherPoint.0),\(AnotherPoint.1))")
    }
    

    #复合匹配
    ***当多个条件可以使用同一种方法来处理时,可以将这几种可能放在同一个case后面,并且用逗号隔开。当case后面的任意一种模式匹配的时候,这条分支就会被匹配。并且,如果匹配列表过长,还可以分行书写 ***

    // switch 中的控制转移语句 (continue, break , fallthrough ,return)
    // continue  continue语句告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代
    // 下面把一串小写字母中的元音字母和空格字符移除
    let SomeCharacter = "great wall is very good"
    var resultCharacter = ""
    for character in SomeCharacter.characters
    {
       switch character {
       case "a","e","i","o","u"," ":
           continue
       default:
           resultCharacter.append(character)
       }
    }
    print(resultCharacter)
    /*
    “在上面的代码中,只要匹配到元音字母或者空格字符,就调用continue语句,使本次循环迭代结束,从新开始下次循环迭代。这种行为使switch匹配到元音字母和空格字符时不做处理,而不是让每一个匹配到的字符都被打印。”
    */
    
    // Break break会立即结束整个控制流的执行
    // Fallthrough(贯穿)  在OC 中不加break会贯穿,swift中不加break也不会贯穿。如果需要贯穿就加上这个关键字
    

    ** #提前退出(guard)**
    *** 像if语句一样,guard的执行取决于一个表达式的布尔值。我们可以使用guard语句来要求条件必须为真时,以执行guard语句后的代码。不同于if语句,一个guard语句总是有一个else从句,如果条件不为真则执行else从句中的代码。 ***

    函数

    1.格式

    函数名 + (参数)-> 返回值类型
    
    func greet(name:String , lunch:String) -> String {
        return "Hello \(name) lunch is \(lunch)"
    }
    greet(name: "steve", lunch: "cookie")    //  "Hello steve lunch is cookie"
    greet(name: "job", lunch: "beef")   //  "Hello job lunch is beef"
    

    2.参数与返回值

    // 无参数
    func sayHelloWorld() -> String {
        return "hello, world”
    }
    print(sayHelloWorld())
    // 打印 "hello, world”
    
    // 多参数
    func sayHello(name:String ,message:String){
        print("\(name) 说 \(message)")
    }
    sayHello(name: "job", message: "我是job,很高兴认识你")
    // 打印 "job 说 我是job,很高兴认识你\n"
    
    // 没有返回值的函数
    func test(hello:String) {
        "hello \(hello)"
    }
    test(hello: "jerry") 
    // 打印 "hello jerry"
    
    // 返回多个值
    func math (numbers:[Int])->(max:Int,min:Int,sum:Int)
    {
        var min = numbers[0]
        var max = numbers[0]
        var sum = 0
        for number in numbers {
            if number < min {
                min = number
            }else if number > max
            {
                max = number
            }
            sum += number
        }
        return (max, min,sum)
    }
    math(numbers: [2,4,8,7])
    // 打印   (.0 8, .1 2, .2 21)
    
    // 带有可变个数参数的函数  “通过在变量类型名后面加入(...)的方式来定义可变参数”
    /*
     “注意: 一个函数至多能有一个可变参数,而且它必须是参数表中最后的一个。这样做是为了避免函数调用时出现歧义。”
      */
    func sumFunction(numbers:Int...)->Int{
        var sum = 0
        for number in numbers {
            sum += number
        }
        return sum
    }
    sumFunction()   // 打印   0
    sumFunction(numbers: 1,2,3)  // 打印   6
    
    
    // 默认参数值,可以在函数体中为每个参数定义一个默认值。当默认值被定以后,调用这个函数时可以忽略这个参数
    func jion(s1:String,s2:String,joiner:String = " ")->String
    {
        return s1 + joiner + s2
    }
    jion(s1: "hello", s2: "world", joiner: "-")      // 打印  "hello-world"
    jion(s1: "hello", s2: "world") // “当这个函数被调用时,如果 joiner 的值没有被指定,函数会使用默认值(" ")”        // 打印     "hello world"
    
    // 函数参数默认是常量,在swift3以前可以在参数列表中加var 来修饰,swift 3之后去除了这种写法,需要写成下面这样
    func exchangeFunc ( num1: Int , num2: Int)
    {
        var num1 = num1
        var num2 = num2
        let temp = num1
        num1 = num2
        num2 = temp
        print("num1:\(num1),num2:\(num2)")  
    }
    exchangeFunc(num1: 3, num2: 9)   //  打印 "num1:9,num2:3\n"
    
    
    //输入输出参数  inout
    // 变量参数 ,只能在函数体内被修改,(默认是值传递)如果想要在一个函数调用结束后使修改的结果还存在,就应该吧这个参数定义为输入输出参数 inout 关键字修饰
    var n1 = 3
    var n2 = 8
    func exchangeFunc1(num1:inout Int,num2:inout Int)
    {
        let temp = num1
        num1 = num2
        num2 = temp
    }
    exchangeFunc1(num1:&n1, num2:&n2) // 调用的时候默认就会加上&取地址符
    print("num1:\(n1),num2:\(n2)")   //  打印  "num1:8,num2:3”
    
    // 函数类型  每个函数都有特定的函数类型,由函数的参数类型和返回类型组成
    // 比如上面的exchangeFunc函数的类型是(Int,Int)-> Int ,没有参数和返回值得类型是()->().(在swift中Void与空的元组是一样的)
    //  函数类型的使用 ,定义一个类型为函数的常量或者变量
    func addTowm (a:Int,b:Int)->Int{
        return a+b
    }
    var myCustomeFunc :(Int,Int)->Int = addTowm
    myCustomeFunc(3,6)
    
    //同样函数类型也可以用类型推断,根据结果推断其函数类型
    var myCustomeFunc1 = addTowm
    //有相同匹配类型的不同函数也可以被赋值给同一个变量
    
    // 函数作为返回值(这里也是用了函数类型作为返回类型)
    
    func returnFunc() -> ((Int) -> Int) {
        func add (number:Int)->Int{
            return number + 10
        }
        return add
    }
    let funcBack = returnFunc()
    funcBack(10)     //  打印  20
    
    // 函数作为参数传入另一个函数(这里是将函数类型作为参数)
    func functionParameter(numbers:[Int],condition:(Int)->Bool)->Bool{
        for _num in numbers {
            if condition(_num) {
                return true
            }
        }
        return false
    }
    func conditionFunc (number:Int)->Bool{
        return number < 10
    }
    functionParameter(numbers: [2,16], condition: conditionFunc)   // 打印 true
    

    闭包

    ***闭包和函数类似,可以理解成函数的简写形式,其本质是匿名的可执行代码块。在该代码块中,封装了其所处环境的所有状态。在闭包之前声明的所有变量和常量都可以被它捕获。 函数和闭包都是引用类型 ,闭包表达式语法可以使用常量、变量和 inout 类型作为参数,不能提供默认值。也可以在参数列表的最后使用可 变参数。元组也可以作为参数和返回值。 ***

    ** 1.格式**

    (参数)-> (返回值类型)
    //  闭包表达式语法有如下一般形式:{(参数名1:类型, 参数名2:类型) -> 返回值类型 in 功能实现 }
    /*
    { (parameters) -> returnType in
        statements
    }
     */
    

    2.使用

    let addClosure = { (num1:Int, num2:Int) -> Int in 
        return num1 + num2
    }
    let minusClosure = { (num1:Int, num2:Int) -> Int in 
        return num1 - num2
    }
    

    3.将闭包作为函数的输入参数

    func calc(num1:Int, num2:Int, closure:(Int, Int) ->Int) -> Int { 
        return closure(num1, num2)
    }
    

    4.调用函数,闭包作为参数传入

    let result1 = calc(100, num2: 200, closure: addClosure)  //  300
    let result2 = calc(100, num2: 200, closure: minusClosure)  // -100
    
    

    枚举

    1.枚举语法
    使用enum关键词来创建枚举并且把它们的整个定义放在一对大括号内:
    多个成员值可以出现在同一行上,用逗号隔开

    enum SomeEnumeration {
        // 枚举定义放在这里
    }
    

    2.枚举的使用

    enum MyEnumeration{
        case West,North,South,East
    }
    var enumHead = MyEnumeration.West
    //enumHead = .East
    enumHead = .South
    
    switch enumHead{
    case .South:
        print("yes ,you are good ")
    case .West:
        print("what out of penguins")
    case .East:
        print("hhh ,is the East")
    case .North:
        print("is the North")
    }
    //  打印结果   "yes ,you are good \n"
    

    类和对象

    类是引用类型,(相当于是只是引用指针指向)(=== 等价于 表示两个类类型的常量或变量引用同一个实例 , == 等于 表示两个实例的值相等或相同)
    1.类的定义

    class shape:NSObject{
        //属性
        // 存储属性
        var numberOfSide = 3
        var width = 10
        var height = 30
        
        //定义计算属性
        var size :Int{
            return width * height
        }
        // 类属性  通过类名进行访问
        static var id = 8
        let type = "shape"
        // 通过重写父类的kvc方法,在用kvc 设置类的属性的时候可以传入类中不存在键值对
        override func setValue(_ value: Any?, forUndefinedKey key: String) {
            
        }
        //swift中调用方法和属性可以不加self
        func subDescription() -> String {
            return "the shape numberOfSide is \(numberOfSide)"
        }
        func author(name:String) -> String {
            return "the author is \(name)"
        }
    }
    

    2.对象--类的实例化

    var shapeClass = shape() //初始化子类
    

    3.对象的属性设置与访问

    shapeClass.numberOfSide = 6 //1. 给类的存储属性赋值,直接赋值
    shapeClass.setValuesForKeys(["numberOfSide":10]) // 2.通过kvc给类的存储属性赋值
    shapeClass.setValue(20, forKey: "numberOfSide")
    print(shapeClass.numberOfSide)
    shapeClass.setValuesForKeys(["numberOfSide":30,"name":"petter"]) // 这里就不会报错,因为上面重写了setValue(_ value: Any?, forUndefinedKey key: String)方法
    var shapeDescription = shapeClass.subDescription()
    var shapeAuthor = shapeClass.author(name: "Ben")
    var type = shapeClass.type
    

    结构体

    // 结构体结构体是被通过复制的方式在代码中传递,不使用引用计数。 
    // 结构体和类的定义方式相似,关键字是struct开头
    // 结构体和枚举都是值类型(值类型被赋予一个变量、常量或者被传递给一个函数的时候,其值会被拷贝)
    
    class SomeClass { // 声明一个类
        var subStruct = SomeStruct()
        var name:String?
        
    }
    
    struct SomeStruct{// 声明一个结构体
        var width = 0
        var height = 0
    }
    
    // 结构体和类声明实例的方式也很相似,都采用的是构造器语法
     let subClass = SomeClass()
     let subStruct1 = SomeStruct()
    
    // 在swift 中可以直接设置结构体属性的子属性的值,在OC 中是不允许的,需要先定义一个中间变量,比如设置frame
    subClass.subStruct.width = 640
    print("subStruct width is now \(subClass.subStruct.width)")
    
    // 成员逐一构造器,用于初始化新结构体实例中成员的属性。类实例没有默认的成员逐一构造器
    let newSubStruct = SomeStruct(width:200,height:300)
    
    // 关于值类型举个例子
    
    // 定义一个结构体实例
    let cnima = SomeStruct(width:1280,height:720)
    // 再声明一个HD变量,将cnima的值赋给他
    var HD = cnima
    //修改HD的width属性值
    HD.width = 2480
    print("now cnima.width is \(cnima.width)") // 打印发现还是1280,并未受到影响,因为cnima 是一个结构体的实例,所以HD其实就是一个cnima的拷贝副本,在幕后他们是完全不同的实例
    
    
    // 枚举
    enum testEnum{
        case west,east,south
    }
    var currentDirectin = testEnum.west
    var memberDirection = currentDirectin
    memberDirection = testEnum.south
    if currentDirectin == .west {
        print("currentDirection still is west")
    }
    

    参考
    Swift3.0基础语法快速入门
    The Swift Programming Language 中文版
    Wiki
    移动开发
    iOS

    相关文章

      网友评论

          本文标题:swift 3.0

          本文链接:https://www.haomeiwen.com/subject/elnzyttx.html