前言:
1.此文中的语法会根据Swift的升级变动而更新。
2.如果需要请移步 -> swift2.2 语法(上)、swift 2.2语法(下)
格式:
func 函数名(参数列表) -> 返回值类型 {
代码块
// 如果设置了返回值类型,就需要返回相应的返回值
return 返回值
}
函数几种定义方式:
// 定义没有参数,没有返回值的函数
// 标准写法
func test1() -> Void {
print("没有参数没有返回值的函数")
}
// 简写方式一
func test2() -> () {
print("没有参数没有返回值的函数")
}
// 简写方式二
func test3() {
print("没有参数没有返回值的函数")
}
// 定义有参数,没有返回值的函数
// 标准写法
func test1(num : Int) -> Void {
print("有参数没有返回值的函数")
}
// 简写方式一
func test2(num : Int) -> () {
print("有参数没有返回值的函数")
}
// 简写方式二
func test3(num : Int) {
print("有参数没有返回值的函数")
}
// 定义没有参数,有返回值的函数
// 标准写法
func test1() -> Int {
return 0
}
// 定义有返回值,有参数的函数
// 标准写法
func test1(num1 : Int, num2 : Int) -> Int {
return num1 + num2
}
// 定义一个有参数,且有多个返回值的函数
// 标准写法
func test1(nums : [String]) -> (strCount : Int, spellString : String) {
var strCount = 0
var spellString = ""
for num in nums {
strCount++
spellString = spellString + num
}
return (strCount, spellString)
}
// 调用函数
print(test1(["abc", "def", "ghi"]))
函数的外部参数和内部参数
// 先来定义一个拥有多个参数的函数
func test1(num1 : Int, num2 : Int, num3 : Int) -> Void {
print(num1, num2, num3)
}
// 在调用函数的时候可以看下区别
/* * 第一个函数没有跟上我们定义参数时所给的标签 * 后面的所有函数都有我们定义参数时所给的标签 * 原因:从第二个参数开始,参数名称即是内部参数也是外部参数(默认) * 也就是说第一个参数默认为内部参数,所以不会显示标签 */
test1(5, num2: 6, num3: 7)
// 先来定义一个拥有多个参数的函数,但是这次我们要让第一个参数也有外部参数
func test1(num1 num1: Int, num2 : Int, num3 : Int) -> Void {
print(num1, num2, num3)
}
// 现在再调用函数可以看到第一个参数也变拥有外部参数
test1(num1: 5, num2: 6, num3: 7)
// 先来定义一个拥有多个参数的函数,这次我们让所有参数都为内部参数
func test1 (num1 : Int, _ num2 : Int, _ num3 : Int) -> Void {
print(num1, num2, num3)
}
// 现在调用函数就会发现所有的参数都成为内部参数了
test1(5, 6, 7)
函数重载
// 函数重载例:定义三个函数,函数名相同但函数的参数不同
// 无返回值,第一个参数为内部参数,第二个参数同时拥有外部和内部参数
func test(num1 : Int, num2 : Int) -> Void {
print("第一个函数")
}
// 无返回值,且都同时没有外部参数
func test(num1 : Int, _ num2 : Int) -> Void {
print("第二个函数")
}
// 无返回值,但同时拥有外部和内部参数
func test(num1 num1 : Int, num2 : Int) -> Void {
print("第三个函数")
}
// 调用函数
test(1, num2: 2)
test(1, 2)
test(num1: 1, num2: 2)
默认参数
// 默认参数
func test(num : Int = 5) -> Int {
return num
}
// 调用参数不给值,返回的的就是默认值 “5”
test()
可变参数
个数
可以变化,可以接收不确定数量
的输入类型参数必须
具有相同的类型参数类型
后面加 “…” 表示参数为可变参数 // 定义函数,参数为可变参数
func test(nums : Int...) -> Int {
var sum : Int = 0
// 遍历内部元素
for temp in nums {
sum += temp
}
return sum
}
// 调用函数,结果为202
test(20, 15, 35, 32, 100)
指针传递(引用类型)
// 比如C语言中常见的问题:交换2个变量的值
// 先来看看正常的值传递
// 定义需要交换值的2个变量a,b
var a = 6
var b = 9
// 值传递方式
func test(var num1: Int, var num2: Int) -> (num1 : Int, num2 : Int) {
let temp = num1
num1 = num2
num2 = temp
return (num1,num2)
}
// 调用函数(交换的只是函数内部参数的值,而a,b的值并没变)
test(a, num2: b) // 结果 9 6
print(a, b) // 结果 6 9
// 通过上面的方式可以明显看出值传递并不能真实转换外部变量的值,在swift中我们可以通 过"inout"关键字来讲外部变量的值传给函数参数,再改变其值
func test(inout num1 : Int, inout num2 : Int) -> (num1 : Int, num2 : Int) {
let temp = num1
num1 = num2
num2 = temp
return (num1, num2)
}
// 调用函数(因为传入的是a,b的变量地址,等于拿到了外部变量,函数内部操作的num1,num2可以看成a,b,因为他们的指针指向了a,b)
test(&a, num2: &b)
print(a,b)
函数嵌套使用
// 函数嵌套
let a = 100
let b = 35
func test() {
func sum(num1 : Int, num2 : Int) {
print("和为\(num1 + num2)")
}
print("test函数")
sum(a, num2: b)
}
// 调用函数
test() // 先调用test函数,再调用sum函数
注意:无法调用sum函数,因为它是test函数的一部分
函数类型
// 函数类型:定义2个函数,且都为 (String, String) -> (String) 类型
func test1(name : String, city : String) -> String {
return name + city
}
func test2(tiele : String, iconUrl : String) -> String {
return "图片名称:\(tiele)图片地址为:\(iconUrl)"
}
将函数作当成变量传递
// 根据函数类型定义变量并将函数传递给变量
var tempFunction : (String, String) -> String = test1
// 使用变量名调用函数
tempFunction("sd", "lw")
// 将函数当成参数使用
func test3(str1 : String, str2 : String, tempFunction : (String, String) -> String) {
print(tempFunction(str1, str2))
}
// 调用函数
test3("aa", str2: "bb", tempFunction: test1) // 结果 aabb
// 函数作为方法返回值
/** * 判断一数是否为负数,是负数返回0,不是则返回原来的值 */
// 正数调用此函数
func positive(num : Int) -> Int {
return num
}
// 负数调用此函数
func negative(num : Int) -> Int {
return 0
}
// 将函数作为返回值
func test(num : Int) -> (Int) -> Int {
// 如果函数小于1就是负数,返回negative函数,如果大于1,则是正数,返回positive函数
return num < 0 ? negative : positive
}
// 获取返回值(函数)
let function = test(-1) // 因为是负数,所以返回negative函数
// 调用方法(再将-1传入返回的函数)
function(-1) // 结果为 0
C语言和OC里面枚举指定的一组相关成员为整型
枚举类型定义
enum
关键词,将定义放在{}内case
关键词定义新枚举成员// 枚举定义
enum testType {
case testTypeOne
case testTypeTwo
case testTypeThree
}
// 当然也可以简写成下面的方式(在枚举成员特别多的情况下很好用)
enum testType {
case testTypeOne, testTypeTwo, testTypeThree
}
枚举类型赋值
枚举类型赋值可以是整型、浮点型、字符、字符串
// 枚举类型赋值
enum testType1 : Int {
case One = 1
case Two = 2
case Three = 3
}
// 或
enum testType2 : Int{
case One = 1, Two, Three
}
枚举类型使用
// 枚举类型赋值(整型)
enum testType1 : Int {
case One = 1
case Two
case Three
}
// 枚举类型赋值(字符串)
enum testType2 : String{
case One = "a", Two = "b", Three
}
let j = testType1(rawValue: 2) // 获取到枚举成员Two
// 结果为Two
if let j = j {
switch j {
case .One:
print("One")
case .Two:
print("Two")
case .Three:
print("Three")
}
}
let i = testType2(rawValue: "a") // 获取到枚举成员One
// 结果为One
if let i = i {
switch i {
case .One:
print("One")
case .Two:
print("Two")
case .Three:
print("Three")
}
}
注意:
1.如果明确了类型为整型且未设置初始值,那么由0开始依次递增(默认)
2.如果明确了类型为整型但设置了初始值,就由初始值依次递增
在特定情况下使用结构体,能使我们的代码结构更清晰
定义结构体格式
struct 结构体名称 {
属性
}
/** * 在手势开发过程中,我们需要监听手指移动的位置,这边我们来判断手指移动的开始位置和结束位置距离是否大于50 */
// 初始化结构体
struct touchPoint {
var x : Double
var y : Double
}
// 定义函数
func Range(point : touchPoint) -> Bool {
let tempX = point.x - startX
let tempY = point.y - startY
// sqrt(n)用来计算n的平方根
// pow(x, n)用来计算x的n次方
let range = sqrt(pow(tempX, 2) + pow(tempY,2))
return range > 50
}
// 创建结构体
let start = touchPoint(x:53.0, y:21.0)
let end = touchPoint(x: 120.0, y: 320.0)
// 调用函数
Range(point) // 结果:true
截止至:5.17 —— 1:00 5.18继续
class
关键字格式:class 类名 : 父类 {
属性,方法
}
类的属性
存储属性
// 定义person类
class person: NSObject {
// 定义存储属性
var name : String? // 名字
var age : Int = 0 // 年龄
}
// 创建person对象
let ps = person()
// 给存储属性赋值
ps.name = "stephen"
ps.age = 23
类属性
static
来修饰 // 定义person类
class person: NSObject {
// 定义存储属性
var name : String? // 名字
var age : Int = 0 // 年龄
// 类属性
static var nickName : String?
}
// 设置类属性值
person.nickName = "laoWang"
// 打印
print(person.nickName!) // 结果:laoWang
计算属性
// 定义person类
class person: NSObject {
// 定义存储属性
var foodIntake : Double = 0.0 // 人的食量(一顿吃几碗)
var consume : Double = 0.0 // 消耗量
// 定义计算属性(差值)
var difference : Double {
get {
return (foodIntake - consume)
}
// newValue是系统自动分配的变量名,内部用来存储新的值
// 里面放的是get方法里面计算的值
set {
self.difference = newValue
}
}
}
// 创建person对象
let ps = person()
ps.foodIntake = 50 // 吃的有点多肯定比我胖
ps.consume = 25 // 消耗这么多惊呆小伙伴,看来是个肌肉男
// 打印
print(ps.difference) // 结果 25.0
newValue
,我们可以给这个参数定义参数名,但一般保持默认)oldValue
class person: NSObject {
var name : String? {
willSet (newValue) { // 属性即将改变时调用
// 会传入系统默认的属性newValue,用来存储新值
print("name:\(name), newValue:\(newValue)") // 结果:name:nil, newValue:Optional("laoWang")
}
didSet (oldValue) {
// 会传入系统默认的属性oldValue,用来存储旧值
print("name:\(name), oldValue\(oldValue)") // 结果:name:Optional("laoWang"), oldValuenil
}
}
}
// 创建person对象
let ps : person = person()
ps.name = "laoWang"
构造函数使用
class person: NSObject {
var name : String
// 因为继承自NSObject,我们就重写(父类)的构造方法
// override关键字表示调用父类方法
override init() {
// 在初始化name属性时没有给它赋值,所以可以在构造函数里面进行赋值
name = "laoWang"
}
}
// 创建person对象
let ps : person = person()
print(ps.name) // 结果:laoWang
初始化时给属性赋值
class person: NSObject {
var name : String
// 自定义构造函数,覆盖init:函数
init(name : String) {
// 在初始化self.name属性时没有给它赋值,所以可以在构造函数里面进行赋值
self.name = name
}
}
// 创建person对象
let ps : person = person(name: "laoWang")
print(ps.name) // 结果:laoWang
字典转模型方式一
class person: NSObject {
var name : String
// 自定义构造函数,覆盖init:函数
init(dict : [String : NSObject]) {
self.name = dict["name"] as! String
}
}
// 创建person对象
let ps : person = person(dict:["name" : "laoWang"])
print(ps.name) // 结果:laoWang
字典转模型方式二
需要注意的是:KVC不能保证给所有属性赋值,所以属性需要有默认的值
class person: NSObject {
// KVC方式下,对象、结构体类型必须是可选类型,否则无法转换
var name : String?
// 自定义构造函数,覆盖init:函数
init(dict : [String : NSObject]) {
// 必须先初始化对象
super.init()
// 调用对象的KVC方法
setValuesForKeysWithDictionary(dict)
}
}
// 创建person对象
let ps : person = person(dict:["name" : "laoWang"])
print(ps.name) // 结果:laoWang