• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

Swift开发语法

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
文/Tuberose(简书作者)
原文链接:http://www.jianshu.com/p/5e2d4c34f18e
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。


简介

  • Swift 语言由苹果公司在 2014 年推出,用来撰写 OS X 和 iOS 应用程序
  • 2014 年,在 Apple WWDC 发布

历史

  • 2010 年 7 月,苹果开发者工具部门总监 Chris Lattner(克里斯·拉特纳) 开始着手 Swift 编程语言的设计工作
  • 用一年时间,完成基本架构
  • Swift 大约历经 4 年的开发期,2014 年 6 月发表

    克里斯·拉特纳
    )

特色

  • 苹果宣称 Swift 的特点是:快速、现代、安全、互动,而且明显优于 Objective-C 语言
  • 可以使用现有的 CocoaCocoa Touch 框架
  • Swift 取消了 Objective C 的指针及其他不安全访问的使用
  • 舍弃 Objective C 早期应用 Smalltalk 的语法,全面改为句点表示法
  • 提供了类似 Java 的名字空间(namespace)、泛型(generic)、运算对象重载(operator overloading)
  • Swift 被简单的形容为 “没有 C 的 Objective-C”(Objective-C without the C)

现状

  • 2015 年 2 月,苹果同时推出 Xcode 6.2 Beta 5 和 6.3 Beta,在完善 Swift 1.1的同时,推出了 Swift 1.2 测试版
  • 2015 年 6 月,苹果在 WWDC 发布了 Swift 2.0 测试版,并且宣称在年底开源
  • 从发布至今,苹果的每一个举措都彰显其大力推广 Swift 的决心
  • Swift 当前正式版本:1.2,测试版本是 2.0
  • 目前有些公司的新项目已经直接采用 Swift 开发
  • 目前很多公司已经在做 Swift 的人才储备
  • 应聘时,会 Swift 开发 无疑会增加自身筹码
  • 到 2015 年底,iOS 9.0 正式发布的同时,Swift 势必大行其道!

资源网站

  • 1.开发入门
    • 简单体验
var i = 10
print(i)
i = 15
print(i)

let j = 20
// 常量一经定义不能自改数值
//        j = 25
print(j)
  • 创建对象
  • 从OC转换为Swift的规律: alloc initXXX --> (xxxx:)
    OC: [[UIView alloc] init] -- [[UIView alloc] initWithFrame:]
    Swift: UIView() -- UIView(frame: )
  • 分号
    • 在OC中每一条语句后面必须跟上一个;, Swift中如果一行只有一条语句, 那么;可以省略
  • 调用方法
    OC: [UIColor redColor];
    Swift: UIColor.redColor()
  • 枚举

    OC: UIButtonTypeContactAdd
    Swift: UIButtonType.ContactAdd
  • 示例

    // 1.创建UIView
    let customView = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
    customView.backgroundColor = UIColor.redColor()
    // 2.创建一个按钮
    let btn = UIButton(type: .ContactAdd)
    btn.center = CGPoint(x: 50, y: 50)
    // 3.将按钮添加到UIView上
    customView.addSubview(btn)

  • 2.常量和变量
// 定义变量
var i = 10
print(i)
i = 15
print(i)

let j = 20
// 常量一经定义不能自改数值
//        j = 25
print(j)
  • 小结

    • var 定义变量,设置之后可以修改
    • let 定义常量,设置之后不可以修改
    • 语句末尾不用使用 ;
    • 在 Swift 中使用 print() 替代 OC 中的 NSLog
    • print 的性能更好
  • 定义 OC 对象

// 实例化视图
let v = UIView(frame: CGRectMake(0, 0, 100, 100))
// 设置背景颜色
v.backgroundColor = UIColor.redColor()

// 添加到根视图
view.addSubview(v)
  • 小结
    • Swift 中要实例化一个对象可以使用 类名() 的格式,与 OC 中的 alloc/init 等价
    • OC 中的 initWithXXXSwift 中通常可以使用 类名(XXX: ) 找到对应的函数
    • OC 中的 [UIColor redColor] 类方法,在 Swift 中通常可以使用 类名.XXX 找到对应的函数
    • 使用 let 修饰 v 并且赋值,表示 该常量的内存地址不允许修改,但是可以修改其内部的属性
    • 当前对象的属性,不需要使用 self.

常量&变量的使用原则:尽量先用 let,只有需要变的时候,再用 var,能够更加安全

  • 变量类型
let x = 10
let y = 10.5
let z: Double = 20

print(Double(x) + y) // 20.5
print(x + Int(y)) // 20
print(y + z) // 30.5
  • 小结
    • 初次接触 Swift 中会因为简单的 var let 误以为 Swift 中的类型非常松散
    • 其实所有变量的准确类型都是在赋值的同时自动推导的
    • Swift 是对类型要求非常严格的一门语言,一个值永远不会被自动转换成其他类型
    • 如果要转换,必须显示转换,Swift 中
      • 小数默认是 Double 类型
      • 整数默认是 Int 类型
    • 如果要显式的指定变量的类型,可以在定义是使用 var 变量名: 类型 = 值
      • 变量: var
      • 常量: let
      • 格式: 修饰符 变量/常量名称: 数据类型 = 值
  • 数据类型
    • 只要将OC中的数据类型第一个字母转换为大写, 就是Swift中的数据类型
  • 注意点:
    • 在Swift开发中, 一般情况下先用let, 只要需要修改数据时才用var, 使用let的好处, 可以避免数据被修改, 可以保证数据安全性
var number: Int = 30
number = 50

let number2: Int = 88
//number2 = 55
  • 类型推导:
    • Swift中如果在定义变量/常量时进行初始化, 那么数据类型可以不用写,系统会自动根据右边的复制推导出变量/常量的类型
    • Swift开发中能不写数据类型就不写数据类型, 尽量使用编译器的自动推导
    • 只有当我们需要明确的指定数据的长度, 获取需要先定义再初始化时才明确的指定数据类型
    • 使用自动类型推导好处: 大大降低代码中的冗余代码
let number3 = 10.10

var number4: Int
number4 = 99
  • 类型转换:
    • OC中有显示转换和隐式转换 double value = 10.1 + 9
    • Swift中只有显示转换没有隐式转换, 也就是说只有相同类型的数据才能进行赋值和计算
// 只有相同数据类型才能赋值
let number5: Int = Int(55.5) // 50

// 只有相同数据类型才能进行运算
let number6 = 10
let number7 = 88.8
let sum = Double(number6) + number7 // 98.8

// CGFloat --> double

let size = CGSize(width: 10, height: 10)
let number8 = 10.1
let sum2 = size.width + CGFloat(number8) // 20.1

  • 3.元祖
let number1 = 10
let number2 = 10.1
  • 元祖

    • 复合数据类型
    • 只要将多个相同或者不同的数据用()括起来就是元祖
    • 优点: 在以前没有元祖之前C和OC语言是通过传入指针或者返回结构体的方式来返回多个值的,而有了元祖之后就可以实现让一个函数返回多个值
let number3: (Int, Double, Int, Double) = (10, 10.1, 9, 44.40) //(.0 10, .1 10.1, .2 9, .3 44.4)
number3.0 // 10
number3.1 // 10.1
number3.2 // 9
number3.3 // 44.40

// 给元祖的元素起名称
let person = (name: "gcy", age: 30, score: 100.0) // (.0 "gcy", .1 30, .2 100)
person.name // "gcy"
person.age // 30
person.score // 100


// 提取元祖的数据
let (name, age, score) = ("gcy", 30, 100.0)
name
age
score

  • 4.分支
var i = 10

if i > 0 {
    print("OK")
}
  • 小结

    • Swift 中没有 C 语言中的非零即真概念
    • 在逻辑判断时必须显示地指明具体的判断条件
    • if 语句条件的 () 可以省略
    • 但是 {} 不能省略
  • if

    • 大部分用于和OC中一致
    • Swif中条件语句可以不用写()
    • OC中如果if后面只有一条语句, 那么{}可以省略, 但是Swift不行
    • OC中条件语句可以是任何数值, OC中非0即真, YES/NO
    • Swift中条件语句的取值必须是Bool类型,
    • 也就是说Swift中提供了真正的Bool类型, true/false
let number = 10
//if number = 10 // Swift有效的避免了这种问题
if number == 10
{
    print(number)
}

let age = 16
if age >= 18
{
    print("开网卡")
}else
{
    print("回家找妈妈")
}
  • 三目运算符
var a = 10
var b = 50

var result = a > b ? a : b
print(result) // 50
  • 小结
    • Swift 中的 三目 运算保持了和 OC 一致的风格
    • 大部分用法和OC一样
    • 条件表达式只能是Bool值
print(age >= 18 ? "开网卡" : "回家找妈妈")
  • switch
    • 大部分用法和OC一样
      Swift中条件语句可以不用写()
    • OC中default可以省略, 而Swift中大部分情况不能省略
    • OC中default的位置可以随便写, 而Swift不可以
    • OC中每个case后面必须加上break, 否则会出现穿透, 而Swift不会穿透, 也就是说不用写break
    • OC中要在case中间定义变量必须加上{}, 否则作用域混乱, 而Swift不用
    • 可以判断区间和元祖
let score = 100
switch score
{
case 59:
    print("不及格")
    var num = 100
case 100:
    print("满分")
default:
    print("Other")
}
  • 区间
    • 闭区间: 0...10 , 取值范围0~10, 包含头包含尾
    • 半闭区间: 0..<10 取值范围0~9, 包含头不包含尾
// 判断区间
switch score
{
case 0..<60: // 0~59
    print("不及格")
case 60..<80: // 60~79
    print("良好")
case 80..<100: // 80~99
    print("优秀")
default:
    print("满分")
}

let point = (100, 50)
// 判断元祖
switch point
{
case (0, 0):
    print("原点")
case (50, 50):
    print("中点")
case (100, 100):
    print("右下角")
default:
    print("Other")
}

// 取出元祖中的值
switch point
{
case (var x, var y) where x > y:
    print(x)
    print(y)
default:
    print("Other")
}

  • 5.可选类型

  • 什么是可选类型: 一个变量可以有值也可以没有值, 我们就称之为可选类型

    • 在Swift中如果使用一个可选类型的变量/常量, 必须解包操作
      • 解包: 只需要在变量/常量后面加上 !
      • !含义: 代表告诉系统该变量/常量中一定有值, 如果强制解包一个没有值的常量/变量,那么会报错
    • 优点: 提高代码阅读性
    • 格式: 修饰符 变量名称:Optional<数据类型> 修饰符 变量名称: 数据类型?
    • 语法糖: 因为在Swift中可选类型用得非常非常多, 所以为了简化代码, Swift提供了一个语法糖, 可以用? 代替 Optional<数据类型>
  • 提示: 对于初学者来说 ? ! 是最为头疼的语法, 刚开始的时候建议利用Xocde的语法提示来解决? !的问题
//var number: Optional<Int> = nil
//var number2: Int = nil

let number: Optional<Int> = 10
print(number!) // 10
let number2 = 10
let sum = number! + number2 // 20


let number3: Int? = 55
print(number3) // "Optional(55)\n"

/*
可选类型注意点:
* 在开发中一般情况下尽量不要强制解包一个可选类型, 否则会引发错误
*/

//let url = NSURL(string: "http://www.baidu.com")
//print(url)
//let request = NSURLRequest(URL: url!) // "Optional(http://www.baidu.com/)\n"

let url = NSURL(string: "http://www.baidu.com/")
print(url)
//let request = NSURLRequest(URL: url!)
if url != nil
{
    let request = NSURLRequest(URL: url!)
}

// 可选绑定: 如果url不为nil, 系统内部就会自动将解包之后的值赋值给temp, 并且只有temp有值时才会执行{}中的代码
// Swift开发中推荐这种写法
if let temp = url
{
    let request = NSURLRequest(URL: temp)
}
  • 演练 1
let url = NSURL(string: "http://www.baidu.com/")

if url != nil {
    NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data, _, _) -> Void in
        print(NSString(data: data!, encoding: NSUTF8StringEncoding))
    }).resume()
}
  • 小结

    • Swift 中,不是所有的对象实例化方法都会返回值,在实际开发中需要注意实例化函数的返回类型,例如:

      convenience init?(string URLString: String)
    • 如果有 ? 表示改方法有可能无法实例化到正确的对象

    • 这种函数返回的对象,被称为 可选项,即有可能有值,也有可能没有值
    • 实际开发时,需要针对这种对象加以判断,并且在分支内部使用 !,指明改对象确实是存在的
    • 相比在 OC 的开发,尤其在日常练习时,会给定一个能够运行的值,而在实际运行时,一旦条件不满足,会直接闪退,这样用户体验会非常不好

Swift 的设计者考虑到因为对类型的强制要求,会让代码很难看,因此提供了一个变通的解决方案

  • 演练 2
if let url = NSURL(string: "http://baidu.com") {
    NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, _, _) -> Void in
        print(NSString(data: data!, encoding: NSUTF8StringEncoding))
    }).resume()
}
  • 小结

    • 使用 if let 常量 = 可选构造函数 的方式能够确保分支内部常量一定是有值的
    • 并且在分支内部不再需要使用 !
    • 这是 Swift 代码中的一个非常重要的使用技巧
  • 提示

    • 尽管 Swift 提供了类型校验的手段,但是要写出 优雅 的 Swift 代码,还是需要多加练习的,否则一不小心就会出现分支嵌套层次很深的代码
    • 有关 ?! 的选择,可以借助 Xcode 的辅助工具,但是强烈建议每次遇到提示时,要多加思考,反复揣摩
  • 演练3

var name: String? // nil
print(name?.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) // "nil\n"

//name = "gcy"
print(name?.lengthOfBytesUsingEncoding(NSUTF8StringEncoding)) // "nil\n"


print((name?.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) ?? 0)) //"0\n"
  • 小结
    • ?? 是一个非常有用的操作符,能够快速对 nil 进行判断
    • 如果对象是 nil,则使用 ?? 后面的值代替前面的 nil 值参与计算
    • 在使用 ?? 时,整个部分需要使用 () 包装
    • 这一技巧在 UITableView 的数据源方法中尤为重要

  • 6.循环
  • OC风格的 for
// 传统写法
for var i = 0; i < 10; i++ {
    print(i) // (10 times)
}
  • Swift风格的 for
// 遍历 0 ~ <10
for i in 0..<10 {
    print(i) // (10 times)
}

print("---") // "---\n"

// 遍历 0 ~ 10
for i in 0...10 {
    print(i) // (11 times)
}
  • 小结

    • Swift 中使用 in 关键字标示循环的范围
    • 0..<10 表示从0到9
    • 0...10 表示从0到10
    • 注意之间不能出现空格
  • 特殊写法

for _ in 0...10 {
    print("hello") // (11 times)
}
  • 小结

    • 如果不关心循环本身的索引,可以使用 _ 忽略
    • 传统for
      • 基本用法和OC一致
      • for后面的()可以省略
      • for后面的{}不可用省略
      • Swift开发中不建议使用传统for循环
for var i = 0; i < 10; i++
{
    print(i) // (10 times)
}

//死循环
for ;;
{
    print("---") // (18657 times)
}
// Swift开发中推荐的for循环格式
for i in 0..<10
{
    print(i) // (10 times)
}
  • while
    • 基本用法和OC一致
var number = 0
while number < 10
{
    print(number) // (10 times)
    number++
}
  • do while
    • 基本用法和OC一致
    • Swift2.0开始dowhile循环中没有do, 只有repeat, 因为do被作用异常处理
var index = 0
repeat{
    print(index) // (10 times)
    index++
}while index < 10

  • 7.数组
    • 数组
      • 格式 var arr: Array<Int> / var arr: [Int]
      • 可变和不可变 var/let
  • 简单体验
let arr = ["zhangsan", "lisi"]
print(arr) // "["zhangsan", "lisi"]\n"

// 遍历每一个元素
for a in arr {
    print(a) // (2 times)
}

// 像 OC 一样打印
print(arr as NSArray) // "(\n    zhangsan,\n    lisi\n)\n"
  • 数组中保存的对象类型
// 数组中保存的都是字符串
let arr = ["zhangsan", "lisi"]

// 数组中保存的是 NSObject
let arr1 = ["zhangsan", 1]
  • 小结

    • 数组使用 [] 定义,这一点与 OC 相同
    • 如果初始化时,所有内容类型一致,则数组中保存的是该类型的内容
    • 如果初始化时,所有内容类型不一致,则数组中保存的是 NSObject
  • 常见数组操作

// 定义只能保存字符串类型数组
var array: [String]

// 初始化数组
array = ["zhangsan"]

// 添加元素
array.append("lisi")

print(array) // "["zhangsan", "lisi"]\n"

// 删除元素
array.removeAtIndex(1) // "lisi"
print(array) // "["zhangsan"]\n"

// 删除所有元素
array.removeAll(keepCapacity: true) // []
print(array.capacity) // "2\n"

// 注意数组容量的变化
for i in 0..<10 {
    array.append("\(i)") // (10 times)
    print("\(array) --- \(array.capacity)") // (10 times)
}

// 实例化新的数组
var array2 = [String]() // []
array2.append("1") //["1"]
array2.append("2") // ["1", "2"]

// 拼接数组
array += array2 // ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "1", "2"]

print(array) // "["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "1", "2"]\n"
  • 小结
    • 如果定义数组时指定了保存对象的类型,择不能向数组中添加其他类型的内容
    • 可以使用 [String]()
    • let 定义的数组是不可变的
    • var 定义的数组是可变的
// 定义数组
//var arr: Array<Int>
//var arr: [Int]
//arr = [1, 2]
var arr = [1, 2]

// 1.遍历数组(取值)
arr[0]
for item in arr
{
    print(item) // (2 times)
}
// 2.添加
arr.append(3)
arr
// 3.修改
arr[1] = 9
arr

// 4.删除
arr.removeAtIndex(0) // 1
arr // [9, 3]

// 5.合并
var arr1 = [3, 5, 7]
arr += arr1 // [9, 3, 3, 5, 7]
arr // [9, 3, 3, 5, 7]

// 6.Swift特殊
for item in arr[0..<2] // 0~1
{
    print(item) // (2 times)
}

//arr.removeRange(Range(start: 0, end: 2))
//arr

// 通过观察可以发现Range其实就是一个半闭区间
arr.removeRange(0..<2) // [3, 5, 7]
arr // [3, 5, 7]

arr += arr1[0..<2] // [3, 5, 7, 3, 5]

  • 8.字典

    • 字典
      • 格式 var dict: Dictionary<String, String>
      • 注意: 将OC的{}换成了[]
      • 可变和不可变 var/let
//var dict: Dictionary<String, String>
//var dict: [String: String]
var dict = ["name": "gcy", "age": "30"]
dict

// 企业开发中字典使用得最多的类型就是 [String: NSObject]类型
var dict2 = ["name": "gcy", "age": 30, "score": 99.9]
dict2

// 取值
dict2["name"]

// 修改
dict2["name"] = "wy"
dict2

// 增加
// 如果key存在就直接修改, 如果key不存在就会增加
dict2["rank"] = 1
dict2

// 删除
dict2.removeValueForKey("name")
dict2

// 遍历
// OC写法
for key in dict2.keys
{
    print(dict2[key]) // (3 times)
}

// Swift写法
// 系统会自动将字典中的key赋值给元祖中的第一个遍历, 会自动将字典中的value赋值给元祖中的第二个遍历
for (xx, oo) in dict2
{
    print(xx) // (3 times)
    print(oo) // (3 times)
}

// 合并
var dict3 = ["name": "gcy", "age": 30]
var dict4 = ["score": 99.9]

// 注意点无论是数组还是字典, 只有相同类型才能赋值
for (key, value) in dict4
{
    dict3[key] = value // 99.9
}
dict3 // ["score": 99.9, "age": 30, "name": "gcy"]

  • 9.字符串

    在 Swift 中绝大多数的情况下,推荐使用 String 类型

  • 使用 String 的原因

  • String 是一个结构体,性能更高

    • String 目前具有了绝大多数 NSString 的功能
    • String 支持直接遍历
  • NSString 是一个 OC 对象,性能略差
  • Swift 提供了 StringNSString 之间的无缝转换

  • 遍历字符串

let str = "我要飞的更High"

for s in str {
    print(s)
}
  • 字符串拼接
let str1 = "zhangsan"
let str2 = "lisi"
let i = 10

print(str1 + str2) // "zhangsanlisi\n"
print("\(str1) \(str2) \(i)") // "zhangsan lisi 10\n"
  • 小结
    • 直接在 "" 中使用 \(变量名) 的方式可以快速拼接字符串
    • 小伙伴们再也不要考虑 stringWithFormat
  • 格式化字符串
for _ in 0...10 {
    let str = String(format: "zhangsan - %04d", arguments: [arc4random_uniform(100)])
    print(str) // (11 times) zhangsan - 0002
}
  • 小结

    • 在实际开发中,如果需要指定字符串格式,可以使用 String(format:...) 的方式
    • 注意:后面的参数需要放在一个数组中
  • String & Range 的结合

以下是超级费劲的代码

let str: String = "beixinke"

var subStr = str.substringWithRange(Range<String.Index>(start: str.startIndex, end: str.endIndex))
print(subStr) // "beixinke\n"
  • 建议写法
let str1: NSString = "beixinke" // "beixinke"
print(str1.substringWithRange(NSMakeRange(0, 3))) // "bei\n"
  • 字符串
    • OC的字符串是NSString, Swift的字符串String
    • OC的字符串是一个对象, Swift字符串是一个结构体, 效率更高
    • OC中的字符串是一个\0结尾, Swift字符串不是以\0结尾
NSString *str = @"abc\0def";
NSLog("%@", str); // abc
  • Swift中的字符串支持遍历
let str = "abc\0def" // "abc�def"
print(str) // "abc�def\n"

// 遍历字符串
for c in str.characters
{
    print(c) // (7 times)
}

// 字符串拼接
var str2 = "gcy"
str2 += str
str2 // "gcyabc�def"

// 字符串格式化
// 可以使用\()在字符串中插入任何数据
let name = "gcy"
let age = 30
let res = "name = \(name), age = \(age)"
res // "name = gcy, age = 30"

// 2015-10-09 03:04
let str3 = String(format: "%d-%02d-%02d %02d:%02d", arguments: [2015, 10, 9, 3, 4]) // "2015-10-09 03:04"

// 截取字符串
// 提示: 在Swift开发中, 我们经常需要将Swift的字符串转换为OC的字符串来操作, 并且Swift自身也意识到了这一点, 所以在OC字符串和Swift的字符串之间转换相当简单
let str4 = "beixinke"
//let str5: NSString = str4
//str5.substringToIndex(4)
//str5.substringWithRange(NSMakeRange(4, 2))

// as 就是把什么当做什么
(str4 as NSString).substringWithRange(NSMakeRange(4, 2)) // "in"

  • 10.函数
  • 简单演练
func sum(a: Int, b: Int) -> Int {
    return a + b
}
  • 小结

    • 函数定义格式:func 函数名(参数: 参数类型...) -> 返回值 { // 代码实现 }
    • 如果没有返回值, -> 返回值 可以省略
    • -> 是一个很有意思的符号
    • 默认情况下,在调用函数时,第一个参数名是省略的
    • Void == ()
  • 参数名的特殊处理

  • 强制要求参数名

func sum1(x a: Int, y b: Int) -> Int {
    return a + b
}
  • 省略参数名
func sum2(a: Int, _ b: Int) -> Int {
    return a + b
}
// 1.没有参数没有返回值
func say() -> Void
{
    print("hi") // "hi\n"
}
say()
// 如果没有返回值可以简写
func say1() -> ()
{
    print("hi") // "hi\n"
}
say1()

func say2()
{
    print("hi") // "hi\n"
}
say2()


// 2.有参数没有返回值
// Swift2.0开始, 会自动将形参列表的第二个参数名称作为标签
// Swift2.0之前是没有这个特性的, 在Swift2.0之前如果需要显示标签需要在形参名称前面加上#
func sum(num1: Int, num2: Int)
{
    print(num1 + num2) // "30\n"
}
sum(10, num2: 20)


// 3.没有参数有返回值
func getNumber() -> Int
{
    return 998
}
print(getNumber()) // "998\n"

// 4.有参数有返回值
func sum2(num1: Int, num2: Int) -> Int
{
    return num1 + num2
}
print(sum2(50, num2: 50)) // "100\n"


// 内部和外部参数
/*
* 默认情况下所有形参都是内部参数, 也就是说只能在函数内部使用
* 从Swift2.0开始会自动将形参列表的第二个参数名称作为标签, 也就是说从第二个参数开始, 参数的名称既是内部参数又是外部参数
* 如何指定外部参数?
*/
func sum3(num1: Int, y num2: Int)
{
    print("num1 = \(num1), num2 = \(num2)") // "num1 = 10, num2 = 20\n"
    print(num1 + num2) // "30\n"
}
//sum3(10, num2: 20)
sum3(10, y: 20)

// 默认参数
// 如果指定了默认值, 那么在调用方法的时候就可以不用传递数据, 如果不传递数据系统就会使用默认值, 如果传递了就会使用传递的值
// 在其它语言里面, 默认值一般情况只能是最后一个参数, 但是Swift可以写在任何位置
func joinString(str1: String, str2: String = "在", str3: String) -> String
{
    return str1 + str2 + str3 // (2 times)
}
joinString("gcy", str2: "也在", str3: "bxk") // "gcy也在bxk"
joinString("wy", str3: "bxk") // "wy在bxk"


// 常量参数和变量参数以及inout参数
// 默认情况下所有形参都是常量参数, 不能在函数中修改形参的值
// 如果想在函数中修改形参的值, 那么必须把形参变为变量参数
// 和OC一样, 在函数中修改形参的值不会影响到外面实参的值
// 如果想在函数中修改形参之后影响实参, 那么必须把形参变为inout参数

//func swap(a: Int, b: Int)
//{
//    let temp = a
//    a = b  // 不能修改常量参数
//    b = temp
//}

//func swap(var a: Int, var b: Int)
//{
//    print("a = \(a), b = \(b)")
//    let temp = a
//    a = b
//    b = temp
//    print("a = \(a), b = \(b)")
//}

func swap(inout a: Int, inout b: Int)
{
    print("a = \(a), b = \(b)") // "a = 10, b = 20\n"
    let temp = a // 10
    a = b // 20
    b = temp //10
    print("a = \(a), b = \(b)") // "a = 20, b = 10\n"
}

var x = 10
var y = 20
print("x = \(x), y = \(y)") // "x = 10, y = 20\n"
swap(&x, b: &y)
print("x = \(x), y = \(y)") // "x = 20, y = 10\n"

// 可变参数
// 只要参数是可变参数, 就可以传递一个或多个值
// 在其它语言中一般情况下可变参数只能是最后一个形参, 而Swift中可以写在任意位置, 但是为了提高代码的阅读性, 还是建议写在最后
func sum4(nums: Int..., temp: Int) -> Int
{
    var sum = 0 // 0
    for i in nums
    {
        sum += i // (3 times)
    }
    return sum + temp // 16
}
sum4(1, 2, 3, temp: 10) // 16

// 函数嵌套
// 将一个函数写到另外一个函数的函数体中, 外面称之为函数嵌套
// 1.被嵌套的函数只能在父函数内部访问
// 2.被嵌套的函数可以访问外部的变量
// 应用场景: 两个函数之间依赖较强, 或者一个函数就只给另外一个函数使用
//          例如: 对数组排序是一个函数, 交换变量又是一个函数, 他们就可以使用函数嵌套
let value = 55 // 55
func test()
{
    let number = 10 // 10
    func demo()
    {
        print("----\(number), \(value)") // "----10, 55\n"
    }
    demo()
}
test()

  • 11.构造函数
    • Swift中要求在创建一个类时必须给这个类中所有的属性进行初始化
    • 如果不能在创建对象时给这个类中所有的属性进行初始化, 那么这些属性必须是可选的
    • 如果已经在构造方法中对所有的属性进行了初始化, 那么这些属性就可以不是可选类型
    • 在给某一个类指定属性的数据类型时, 如果该属性是对象类型, 那么可以指定为可选类型
    • 如果该属性不是对象类型而是基本数据类型, 那么建议直接赋值为0
      • 调用 super.init()的目的主要是为了给对象分配存储空间
    • Swift中如果想在构造方法中使用KVC转换模型, 必须先调用 super.init()
class Person: NSObject {

    var name: String?
    // 如果属性是基本数据类型, 并且是可选类型, 系统不会自动分配存储空间
    var age: Int = 0

//    var name: String
//    var age: Int


    // Person()
    override init() {
        // 注意: 在构造方法中必须先初始化本类再初始化父类
        name = "gcy"
        age = 24
        // 当我们重写一个类的构造方法时, 系统内部会悄悄的帮我们调用super.init()
        super.init()

    }


    // 自定义构造方法
    init(name: String, age: Int)
    {
        self.name = name
        self.age = age
//        以下这一句代码, 能不写就不写
//        super.init()
    }

    init(dict: [String: AnyObject])
    {
        // 注意:Swift中如果想在构造方法中使用KVC转换模型, 必须先调用 super.init()
        super.init()
        setValuesForKeysWithDictionary(dict)
    }

    // Swift中打印对 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Swift去除两边的特定字符(空格或其它)发布时间:2022-07-13
下一篇:
Swift实现iOS录音与播放音频功能发布时间:2022-07-13
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap