swift语言学习
函数
- 函数是用来完成特定任务的独立的代码块。
- 函数声明: 告诉编译器函数的名字,返回类型及参数。
函数定义: 提供了函数的实体。
1.函数定义
- 定义函数使用关键字func。
- 定义函数可以指定一个或多个输入参数和一个返回值类型。
- 每个函数都有一个函数名来描述它的功能。//函数名要有意义
func 函数名(形参) -> 返回类型{
//body of the function
return 形参
}
func double(value: Int) -> Int{
let result = value * 2
return (result)
}
2.函数调用
- 通过函数名以及对应类型的参数值来调用这个函数。
- 函数的参数传递的顺序必须与参数列表相同。
func greet(person: String) -> String{
let greeting = "Hello," + person + "!"
return greeting
}
print(greet(person: "Anna"))
//Hello,Anna!
3.函数举例
(1)没有参数也没有返回值的函数
func sayHello() {
print("Hello!")
}
sayHello()
//Hello!
- 当我们调用此函数时,只需要:
sayHello() - 尽管这个函数没有参数,但是定义中在函数名后还是需要一对圆括号。当被调用时,也需要在函数名后写一对圆括号。
(2)不带参数的函数
func sitename() -> String {
return "菜鸟教程"
}
print(sitename())
(3)没有返回值函数
func runoob(site: String) {
print("菜鸟教程官网:\(site)")
}
runoob(site: "http://www.runoob.com")
4.函数参数
- 函数的参数可以是一个或者多个
import UIKit
func multiply(firstNumber: Int, secondNumber: Int){
let result = firstNumber * secondNumber
print("The result is \(result).")
}
multiply(firstNumber: 10, secondNumber: 5)
//The result is 50.
4.函数参数名称
局部参数名
局部参数名在函数的实现内部使用。
func sample(number: Int) {
println(number)
}
以上实例中 number 为局部参数名,只能在函数体内使用。
外部参数名(参数标签和参数名称)
你可以在局部参数名前指定外部参数名,中间以空格分隔,外部参数名用于在函数调用时传递给函数的参数。
func sayHello(to person: String, and anotherPerson: String){
print("Hello \(person) and \(anotherPerson)")
}
sayHello(to: "Luke", and: "Dave")
如果你提供了外部参数名,那么函数在被调用时,必须使用外部参数名。
- 不指定参数标签时,参数标签默认与参数名称相同
- 如果想忽略参数标签时,在参数标签的位置用下划线代替
func sayHello(_ person: String, _ anotherPerson: String){
print("Hello \(person) and \(anotherPerson)")
}
sayHello("Luke", "Dave")
5.参数默认值
- 函数参数可以有默认值,通常来说,带有默认值的参数位于最后
func display(teamName: String, score: Int = 0){
print("\(teamName): \(score)")
}
display(teamName: "Wombats",score: 100)
//Wombats: 100
display(teamName: "Wombats")
//Wombats: 0
6.输入输出参数
- 函数参数默认是常量。也就是这个参数你只可以查询使用,不能改变它的值。在函数体中更改参数值将会导致编译错误。
- 如果你想要一个函数可以修改参数的值,并目想要在这些修改在函数调用结束后仍然存在,那么就应该把这个参数定义为输入输出参数。
- 在参数定义前加 inout 关键字,这样就可以改变这个参数的值了。
- 当传入的参数作为输入输出参数时,需要在参数名前加 & 符,表示这个值可以被函数修改。
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}//交换a,b的值
var a = 3
var b = 5
swapTwoInts(&a,&b)
print(a)//5
print(b)//3
7.函数类型
- 每个函数都有种特定的函数类型,由函数的参数类型和返回类型组成。
- 以下例子函数类型是(Int,Int)->Int
func addTwoInts(a: Int, b: Int) -> Int{
return a + b
}
func multiplyTwoInts(a: Int, b: Int) -> Int{
return a * b
}
- 在 Swift 中,使用函数类型就像使用其他类型一样。例如,你可以定义一个类型为函数的常量或变量,并将适当的函数赋值给它:
var mathFunction: (Int, Int) -> Int = addTwoInts
print(mathFunction(3,5))//8
- 有相同匹配类型的不同西数可以被赋值给同一个变量,就像非函数
类型的变量一样:
mathFunction = multiplyTwoInts
print(mathFunction(3,5))//15
- 函数类型作为参数类型、函数类型作为返回类型
- 我们可以将函数作为参数传递给另外一个参数:
func sum(a: Int, b: Int) -> Int {
return a + b
}//函数类型作为返回类型
var addition: (Int, Int) -> Int = sum
print("输出结果: \(addition(40, 89))")
//函数类型作为参数类型
func another(addition: (Int, Int) -> Int, a: Int, b: Int) {
print("输出结果: \(addition(a, b))")
}
another(addition: sum, a: 10, b: 20)//输出结果: 30
8.函数嵌套调用
- 函数嵌套指的是函数内定义一个新的函数,外部的函数可以调用函数内定义的函数。
- 除了从外部调用函数以外,也可以在一个函数中调用另一个函数。
//求a到b区间平方和
func square(x: Int) -> Int{
return x * x
}
func sumOfSquare(a: Int, b: Int) -> Int{
var result = 0
for i in a...b{
result += square(x: i)
}
return result
}
sumOfSquare(a: 1, b: 10)
9.函数递归调用
- 函数甚至可以自己调用自己,这种方式叫做函数的递归调用。
- 考虑编写一个阶乘函数,例如5!=5* 4* 3* 2* 1=120。
- 数学上规定 0!= 1。
func fact(_ x: Int) -> Int {
if x == 0{
return 1
}
return x * fact(x - 1)
}
fact(5)
结构体
结构体是构建代码所用的一种通用且灵活的构造体。
我们可以为结构体定义属性(常量、变量)和添加方法,从而扩展结构体的功能。
- 结构体可以组合不同类型的数据
- 结构体总是通过被复制的方式在代码中传递,因此它的值是不可修改的。
struct Student {
var name = "Bob"
var age = 19
}
- 结构体的成员变量叫做结构体的属性//如上的name和age。
- 创建结构体实例//不同学生
- 通过. 号来访问结构体成员的值。
var Student1 = Student()//将结构体Student()实例化并传递给Student1
print("student1的名字是\(Student1.name)")//student1的名字是Bob
print("student1的年龄是\(Student1.age)岁")//student1的年龄是19岁
- 结构体带参初始化
var Student2 = Student(name:"Tony",age: 12)
- 储存属性和计算属性
struct Student {
var name:String = "Bob"
var age:Int = 19
var birthYear: Int{//计算属性
return 2023 - age
}
}
- 计算属性的get方法
- 只有get方法的计算属性也被称为只读计算属性
var birthYear: Int{
get{
return 2023 - age
}//只读
}//只能改变age的值不能改变birthYear的值
var birthYear: Int{
get{//get只有一个表达式可以省略return
return 2023 - age
}
set(newBirthYear){//计算属性的set方法
age = 2023 - newBirthYear
}//age,birthYear两个值可以互相修改
}
- 计算属性set方法隐含了名为newvalue的变量//newBirthday可以省略
set{
age = 2023 - newValue
}
- willSet和didSet属性观察器
var age:Int = 19{
willSet{
print("年龄即将从\(age)岁变为\(newValue)岁")
}
didSet{
print("年龄已经从\(oldValue)岁变为\(age)岁")
}
}
- 结构体的成员函数叫结构体的方法
struct Student {
var name:String = "Bob"
func sayHello() {
print("I am \(name)")
}
}
var student1 = Student()
student1.sayHello()//I am Bob
- self关键字调用自身属性
struct Student {
var name:String = "Bob"
func sayHello(to name: String) {
print("Hello \(name),I am \(self.name)")
}
}
var student1 = Student()
student1.sayHello(to: "Anna")//Hello Anna,I am Bob
- mutating关键字,在方法里要改变属性的值就需要加mutating
struct Student {
var name:String = "Bob"
mutating func changeName(to name: String) {
self.name = name
}
}
var student1 = Student()
student1.changeName(to: "Anna")
print(student1.name)//Anna
- 常量结构体无法调用mutating方法
类
Swift 并不要求你为自定义类去创建独立的接口和实现文件。你所要做的是在一个单一文件中定义一个类,系统会自动生成面向其它代码的外部接口。
- 类与结构体类似,用class关键字定义
struct Resolution{
var width: Int = 0
var height: Int = 0
}
class VideoMode {
var resolution = Resolution()
var name: String?
}
//创建类的实例
let someVideoMode = VideoMode()
print(someVideoMode.resolution.width)//0
someVideoMode.resolution.width = 1080
print(someVideoMode.resolution.width)//1080
- 类也可以拥有自己的属性和方法,并且不需要mutating关键字
class Counter{
var count = 0
func increment(){
count += 1
}
}
- 类与结构体的区别之一在于类可以继承
- 继承的作用是在一个已有类的基础上创建一个新的类
- 继承类叫做子类,被继承类被叫做父类(或超类)
- 没有继承其他类的类,称为基类
class 子类名: 父类名{
//子类内容
}
class Vehicle{
var currentSpeed: Double = 0.0
var description: String{
return "Current speed: \(currentSpeed)!"
}
func makeNoise() {
}
}
class Car: Vehicle{
var brand: String = "W"
}
var car1 = Car()
car1.currentSpeed = 30.0
print(car1.brand,car1.currentSpeed)//W 30.0
- 在子类中,可以通过override关键字重写父类的方法
class Car: Vehicle{
var brand: String = "W"
override func makeNoise() {
print("choo choo")
}
}
car1.makeNoise()//choo choo