简介
Swift 学习
Swift类型
Float
String
Int
Swift基础初步
1.代码每行不需要 分号结束;
2.代码没有 python 那样 严格的 空格格式
3.使用 var定义变量 使用 let 定义常量
4.swift代码调用过程类似脚本语言 可以不用main入口函数 顺序执行
5.字符串以u开头标示为 unicode编码let blackHeart = "\u{2665}" 标示 ♥
6.函数定义
func PrintNode(_ list: ListNode?) -> Void{} 【Swift】
public static void main(String[] args) {} 【Java】
7.Java中标示的null 在 Swift 中 标示为 nil
8.值永远不会被隐式转换为其他类型。如果你需要把一个值转换成其他类型,请显式转换
let label = "The width is"
let width = 94
let widthLabel = label + String(width) // 【Swift必须显示强制转换】
String A ="123"; int B = 4; System.out.println(A+B); // 【java 隐式转换】
一种更简单的把值转换成字符串的方法:把值写到括号中,并且在括号之前写一个反斜杠(\)
\(数值)的写法必须放在字符串内部 而不能放在外部如"I have apples."+\(apples)【报错】
let apples = 3
let oranges = 5
let appleSummary = "I have \(apples) apples."
let fruitSummary = "I have \(apples + oranges) pieces of fruit."
9.方括号 [] 来创建数组 Array 和 字典Map 并使用下标和键(key)来访问元素
Array数组只有下标数值[0....length-1],
Map只有下标key键 Map[(Key1,Value2),(Key1,Value2)] 不能数值访问
═══════════════════════════════════════════════════════════════
var shoppingList = ["catfish", "water", "tulips", "blue paint"]
print(shoppingList[1])
shoppingList[1] = "bottle of water"
print(shoppingList[1])
var occupations = [
"Malcolm": "Captain",
"Kaylee": "Mechanic",
]
print(occupations["Malcolm"])
occupations["Malcolm"] = "Public Relations"
print(occupations["Malcolm"])
═════════════════════
water
bottle of water
Optional("Captain")
Optional("Public Relations")
═══════════════════════════════════════════════════════════════
10.初始化语法来创建一个空数组或者空字典
可以不用定义初始化长度 类似ArrayList区别于String[]
数组[]------var arr = [类型]()
字典[Key,Value]------ var dic=[Key类型,Value类型]()
let emptyArray = [String]()
let emptyDictionary = [String: Float]()
var shoppingList = [] // 简化新式 arr
var occupations = [:] // 简化新式 dic
═══════════════════════════════════════════════════════════════
var emptyArray = [String]()
var aa = "0"
var bb = "1"
// emptyArray[0] = aa // 这里向空数组的 下标0 赋值 会导致错误
// emptyArray[1] = bb // 猜测为当前还没有下标0的值 必须追加才有
emptyArray.append(aa)
emptyArray.append(bb)
print(emptyArray[0])
print(emptyArray[1])
print(emptyArray)
═════════════════════
0
1
["0", "1"]
═══════════════════════════════════════════════════════════════
var emptyArray = [String]() ;emptyArray[0] = "0";print(emptyArray)
//当前报错 Fatal error: Index out of range: file 因为空数组没有下标为0的值(未初始化)
11. if 条件控制操作( 没有圆括号包围 判断语句 )
═══════════════════════════════════════════════════════════════
var teamScore = 91
if teamScore >= 60 && teamScore >= 70 {
print("当前分数\(teamScore) 及格 评分:良-")
}else if teamScore >= 70 && teamScore >= 80 {
print("当前分数\(teamScore) 及格 评分:良")
}else if teamScore >= 80 && teamScore >= 90 {
print("当前分数\(teamScore) 及格 评分:良+")
}else if teamScore >= 90 && teamScore >= 100 {
print("当前分数\(teamScore) 及格 评分:优")
} else {
print("当前分数\(teamScore) 不及格 评分:差")
}
═════════════════════
当前分数91 及格 评分:良-
═══════════════════════════════════════════════════════════════
12. switch 去除掉冗余的break了,必须保留 default:分支 否则报错
switch 支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等
甚至能在case语句中执行 查询的操作 这个 很舒服的操作啊~~~
═══════════════════════════════════════════════════════════════
let vegetable = "red pepper"
var selected_index = -1
switch vegetable {
case "celery":
print("Add some raisins and make ants on a log.")
selected_index = 1
case "cucumber", "watercress":
print("That would make a good tea sandwich.")
selected_index = 2
case let x where x.hasSuffix("pepper"): // 在 case 中 判断当前字符串是否以 pepper结尾 并把匹配的字符串复制给了 常量x
print("Is it a spicy \(x)?")
selected_index = 3
default:
print("Everything tastes good in soup.")
}
print("selected_index is \(selected_index)")
═════════════════════
Is it a spicy red pepper?
selected_index is 3
═══════════════════════════════════════════════════════════════
13. for-in循环操作
for 【item】 in 【list】 {}
if 语句中,条件必须是一个布尔表达式——这意味着像 if score { ... } 这样的代码将报错,而不会隐形地与 0 做对比
═══════════════════════════════════════════════════════════════
let individualScores = [11, 22, 33, 44]
var teamScore = 0
for score in individualScores {
teamScore+=score
}
print(teamScore)
═════════════════════
110
═══════════════════════════════════════════════════════════════
for 【key,value】 in 【Dic】
for-in 来遍历字典,需要一对儿变量来表示每个键值对
字典是一个无序的集合,所以他们的键和值以任意顺序迭代结束
═══════════════════════════════════════════════════════════════
let interestingNumbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var kindCount = 0
for (kind, numbers) in interestingNumbers { // 双重遍历
for number in numbers {
if number > largest {
largest = number
}
}
kindCount+=1
}
print("the dic size is \(kindCount) |||| max value in dic is \(largest)") // 打印 value==Array<int> 最大的那个
═════════════════════
the dic size is 3 |||| max value in dic is 25
═══════════════════════════════════════════════════════════════
14. while 循环操作
while 来重复运行一段代码直到条件改变。
═══════════════════════════════════════════════════════════════
var sum = 0
var n = 0
while n < 4 {
n += 1
sum = sum + n
print("n = \(n) sum=\(sum)") // 1开始连续累加
}
print("End--> n = \(n) sum=\(sum)") // 1开始连续累加
═════════════════════
n = 1 sum=1
n = 2 sum=3
n = 3 sum=6
n = 4 sum=10
End--> n = 4 sum=10
═══════════════════════════════════════════════════════════════
15. repeat-while循环操作
repeat-while 循环条件在结尾,保证能至少循环一次
═══════════════════════════════════════════════════════════════
var m = 1
var n = 0;
repeat {
m *= 2
n += 1
} while m < 12345
print("value = \(m) 2的\(n)次方 ") // 离 12345 最近的 2次方的数值
═════════════════════
value = 16384 2的14次方
═══════════════════════════════════════════════════════════════
16. 类型? 标示在当前类型追加一种可选机制 当前真实值允许为nil 空 配合 if let 使用来判断当前的 类型? 的值 并把它的类型 赋值给中间变量类型 type 完成 从 type?-->type
if let 中间常量 = type?
如果变量的可选值 type? 是 nil,条件会判断为 false,大括号中的代码会被跳过。如果不是 nil,会将值解包并赋 给 let 后面的常量,这样代码块中就可以使用这个值了
═══════════════════════════════════════════════════════════════
var optionalStringA: String? = "Hello"
print(optionalStringA == nil)
var optionalStringB: String? = nil
print(optionalStringB == nil)
if optionalStringA == "Hello" {
print(String("optionalStringA = \(optionalStringA)" ))
}
if let itemStrA = optionalStringA {
print(String("optionalStringA = \(itemStrA)"))
}
if let itemStrB = optionalStringB {
print(String("optionalStringB = \(itemStrB)" ))
}else{
print("optionalStringB is nil ")
}
═════════════════════
false
true
optionalStringA = Optional("Hello")
optionalStringA = Hello
optionalStringB is nil
═══════════════════════════════════════════════════════════════
17. ??符号 类型? 为 nil时设置默认值时使用?? 出现在字符串 \( optionlStr ?? defaultStr) 节省判断的代码量了
let nickName: String? = nil
let fullName: String = "John Appleseed"
let informalGreeting = "Hi \(nickName ?? fullName)"
print(informalGreeting) // 打印 Hi John Appleseed
18. swift 语言中 没有 ++ -- 这样的自增 自减符号
var n = 2
// n++ // 报错
// n-- // 报错
n-=1
print("n = \(n)") // n = 1
n+=1
print("n = \(n)") // n = 2
19. ..< 和 ... 符号
..< 来表示数值范围 包含下界 不包含上界
... 来表示数值范围 包含下界 也 包含上界
═══════════════════════════════════════════════════════════════
for i in 0..<5 {
print("i = \(i)")
}
═════════════════════
i = 0
i = 1
i = 2
i = 3
i = 4
═══════════════════════════════════════════════════════════════
═══════════════════════════════════════════════════════════════
for i in 0...7 {
print("【i】 = \(i)")
}
═════════════════════
【i】 = 0
【i】 = 1
【i】 = 2
【i】 = 3
【i】 = 4
【i】 = 5
【i】 = 6
【i】 = 7
═══════════════════════════════════════════════════════════════
20.
21.
Swift函数与闭包
1.使用 func 来声明一个函数,使用名字和参数来调用函数。使用 -> 来指定函数返回值的类型
函数调用时 必须显示的 标注 输入参数标签, 并且参数位置不可以调换 否则报错
func greet(person: String, day: String) -> String {
return "Hello \(person), today is \(day)."
}
print(greet(person:"张三", day: "周一")) // Hello 张三, today is 周一.
// print(greet(person:"张三", "周一")) // 报错
// print(greet("张三", day: "周一")) // 报错
// print(greet( day: "周一",person:"张三")) // 报错
// print(greet("张三", "周一")) // 报错
2.参数标签(参数别名) 和 默认参数别名_
默认情况下 定义函数必须给定 参数标签 ,但可以使用参数别名来给同一个参数定义一个新的 参数别名 并且新调用函数必须使用新别名 同时使用 _ 来标示当前参数标签在调用时 不用强制写标签
【新的参数别名 必须被强制使用 在调用函数处必须改为新的参数别名】
【使用_ 那么就强制不用输入参数别名 , 强制使用就报错】
【不使用_ 那么就必须强制使用标签名称】
func greet(_ person: String,_ day: String) -> String {
return "Hello \(person), today is \(day)."
}
// print(greet(person:"张三", day: "周一")) // 报错 强制使用报错
// print(greet(person:"张三", "周一")) // 报错
// print(greet("张三", day: "周一")) // 报错
// print(greet( day: "周一",person:"张三")) // 报错
print(greet("张三", "周一")) // 正常运行 Hello 张三, today is 周一.
3.多参数标签(参数别名)
func greet(one person: String,two day: String) -> String {
return "Hello \(person), totwo is \(day)."
}
// print(greet(person:"张三", day: "周一")) // 报错 强制使用报错 必须使用 新的标签名称 为什么这么操作????? 必须使用新的参数别名
print(greet(one:"李四", two: "周二")) //
4.使用元组来生成复合值,比如让一个函数返回多个值。
太方便,因为在Java中 要返回指定的两个int值,那么就必须创建新的类比如Rect 才能往下走 元祖拿来就用....而且元祖的属性可以自定义
═══════════════════════════════════════════════════════════════
func calculateStatistics(scores: [Int]) -> (min: Int, max: Int, sum: Int) {
var min = scores[0]
var max = scores[0]
var sum = 0
for score in scores {
if score > max {
max = score
} else if score < min {
min = score
}
sum += score
}
return (min, max, sum)
}
let statistics = calculateStatistics(scores:[1, 2, 3, 4, 5])
print("statistics.min ==\(statistics.min)") // 元祖的参数表示法
print("statistics.max ==\(statistics.max)") // 元祖的参数表示法
print("statistics.sum ==\(statistics.sum)") // 元祖的参数表示法
print("statistics.0 ==\(statistics.0)") // min: Int // 元祖的下标序号表示法
print("statistics.1 ==\(statistics.1)") // max: Int // 元祖的下标序号表示法
print("statistics.2 ==\(statistics.2)") // sum: Int // 元祖的下标序号表示法
═════════════════════
输入参数: scores:[1, 2, 3, 4, 5]
statistics.min ==1
statistics.max ==5
statistics.sum ==15
statistics.0 ==1
statistics.1 ==5
statistics.2 ==15
═══════════════════════════════════════════════════════════════
5.嵌套函数 外层函数可调用下一级的内层函数形成嵌套函数,但不能跨层级调用
并且在调用 嵌套函数时 该函数必须出现在该函数定义 之后 否则报错
═══════════════════════════════════════════════════════════════
func returnFifteen() -> Int {
var y = 10
func add() {
func add_5() {
print("add_B_Begin")
y += 5
print("add_B_End")
}
print("add_A_Begin")
add_5()
print("add_A_End")
}
add()
// add_5() // 这里跨级 调用 将会报错
return y
}
print("result == \(returnFifteen())")
═════════════════════
add_A_Begin
add_B_Begin
add_B_End
add_A_End
result == 15
═══════════════════════════════════════════════════════════════
6.函数可以作为返回值 函数可以赋值为变量
函数是第一等类型,这意味着函数可以作为另一个函数的返回值
好处 可以把匿名函数这类东西传递出去 实现函数的复用 不用重复定义利于统一管理
═══════════════════════════════════════════════════════════════
func makeJieCheng() -> ((Int) -> Int) {
func jiecheng(number: Int) -> Int {
var temp = 1;
for i in 1...number{
temp *= i
}
return temp
}
return jiecheng
}
var jiecheng = makeJieCheng()
print("1! = \(jiecheng(1)) ")
print("2! = \(jiecheng(2)) ")
print("3! = \(jiecheng(3)) ")
print("4! = \(jiecheng(4)) ")
print("5! = \(jiecheng(5)) ")
═════════════════════
1! = 1
2! = 2
3! = 6
4! = 24
5! = 120
═══════════════════════════════════════════════════════════════
7.函数作为参数 进行调用
函数既然能作为返回值返回给 变量, 那么这个变量 也可以作为参数被其他函数调用
虽然调用这样以函数为参数的时候不怪,但是这样的函数定义起来看起来怪
═══════════════════════════════════════════════════════════════
// condition 是一个接受一个 Int 返回 Bool的函数参数
func has_zige(list: [Int], condition: (Int) -> Bool) -> Bool {
for item in list {
if !condition(item) {
return false
}
}
return true
}
// 每门课程 大于 60 算及格,只要出现不及格的课程 就没有资格申请奖学金
func isJieGe(number: Int) -> Bool {
return number > 60
}
var A_scores = [59, 80, 74, 90]
var B_scores = [66, 77, 88, 90]
has_zige(list: B_scores, condition: isJieGe)
print("奖学金申请标准: 每门课程 大于 60 算及格,只要出现不及格的课程 就没有资格申请奖学金")
print("A 分数\(A_scores)")
print("B 分数\(B_scores)")
print("A 是否有资格申请奖学金: \(has_zige(list: A_scores, condition: isJieGe))")
print("B 是否有资格申请奖学金: \(has_zige(list: B_scores, condition: isJieGe))")
═════════════════════
奖学金申请标准: 每门课程 大于 60 算及格,只要出现不及格的课程 就没有资格申请奖学金
A 分数[59, 80, 74, 90]
B 分数[66, 77, 88, 90]
A 是否有资格申请奖学金: false
B 是否有资格申请奖学金: true
═══════════════════════════════════════════════════════════════
8.闭包 匿名的函数 { 【partA】in【partB】} 被包括在{} 里 没有名称. 但注意哈 他可以被当做参数与返回值进行传递 那么它的作用就扩大了啊 就不仅仅限于一地之用了
使用 {} 来创建一个匿名闭包。使用 in 将参数和返回值类型的声明与闭包函数体进行分离
尼玛 这个 in 很容易忘记啊........
═══════════════════════════════════════════════════════════════
//______________________________________
// 参数==void 返回值==void 的 闭包
var hello_swift = { // 参数==void 返回值==void 的 闭包 省略in 关键字
print("参数==void 返回值==void 的 闭包 --> Hello Swift")
}
hello_swift() // Hello Swift
hello_swift = { // 闭包被覆盖 参数==void 返回值==void 的 闭包 省略in 关键字
print("参数==void 返回值==void 的 闭包 --> Hello World")
}
hello_swift() // Hello World
//______________________________________
// 参数==Int 返回值==void 的 闭包
var int_void_close = {
( number : Int ) -> Void in
print("参数==Int 返回值==void 的 闭包 --> int_void_close(100) int is \(number)")
}
int_void_close(100) // int_void_close int is 100
//______________________________________
// 参数==Int 返回值==Int 的 闭包
var int_int_close_addself = {
( number : Int ) -> Int in
let numer_temp = number
return numer_temp+1
}
//int_int_close_addself(100) == 101
print("参数==Int 返回值==Int 的 闭包 --> int_int_close_addself(100) == \(int_int_close_addself(100))")
//______________________________________
═════════════════════
参数==void 返回值==void 的 闭包 --> Hello Swift
参数==void 返回值==void 的 闭包 --> Hello World
参数==Int 返回值==void 的 闭包 --> int_void_close(100) int is 100
参数==Int 返回值==Int 的 闭包 --> int_int_close_addself(100) == 101
═══════════════════════════════════════════════════════════════
9.更简洁的闭包表达式
有很多种创建更简洁的闭包的方法。如果一个闭包的类型已知,比如作为一个代理的回调,你可以忽略参数,返回值,甚至两个都忽略。单个语句闭包会把它语句的值当做结果返回
═══════════════════════════════════════════════════════════════
var numbers = [1,2,3,4,5]
// 数组的map 就已经决定了它接受的闭包是一个 Int -> Int 类型的闭包 所以下面省略写法
let mappedNumbers = numbers.map({ number in 3 * number })
print("mappedNumbers == \(mappedNumbers)")
═════════════════════
mappedNumbers == [3, 6, 9, 12, 15]
═══════════════════════════════════════════════════════════════
10.$1 $2 在闭包中的应用
当一个闭包是传给函数的唯一参数,你可以完全忽略括号。
$10===第一个参数 可以通过参数位置而不是参数名字来引用参数
$1===第二个参数 可以通过参数位置而不是参数名字来引用参数
$2===第三个参数 可以通过参数位置而不是参数名字来引用参数
═══════════════════════════════════════════════════════════════
var numbers = [1,2,4,3,4,6,5]
// 数组的sorted 就已经决定了它接受的闭包是一个 (Int:Int)->Boolean 类型的闭包 所以下面省略写法
let sortedNumbers = numbers.sorted { $0 > $1 }
print("sortedNumbers == \(sortedNumbers)")
═════════════════════
sortedNumbers == [6, 5, 4, 4, 3, 2, 1]
═══════════════════════════════════════════════════════════════
11.da
12.da
13.da
14.da
15.da
16.da
17.da
18.da