swift3.0

简书迁移过来

##导入格式 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
** 常量的值不可以去修改 **
复制代码

运行结果

#变量

// 变量
//指定变量类型
var bString :String
bString = aString
var cInt:Int
cInt = bInt

// 不指定类型
var dInt = bInt

//修改值
dInt = 0000
bString = "it`s can change"
复制代码

运行结果

##二、数值类型转换

// 整数和浮点型转换
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")
}
复制代码

** #匹配区间**

// 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

转载于:https://juejin.im/post/5a7908da6fb9a063586559d1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值