望其项背 iOS - swift: 变量,常量,基本数据类型,类型转换,类型别名,元组,可空类型,运算符,??,类型后跟!和?,值后跟!和?,m...n,m...,...n,m..<n,控制台打印数据,注释可嵌套,语句末尾可以不加分号,数据转换
望其项背 iOS - swift: 变量,常量,基本数据类型,类型转换,类型别名,元组,可空类型,运算符,??,类型后跟!和?,值后跟!和?,m...n,m...,...n,m..<n,控制台打印数据,注释可嵌套,语句末尾可以不加分号,数据转换
示例如下:
SwiftView01.swift
/*
* 本例用于演示变量,常量,基本数据类型,类型转换,类型别名,元组,可空类型,运算符,??,类型后跟!和?,值后跟!和?,m...n,m...,...n,m..<n,控制台打印数据,注释可嵌套,语句末尾可以不加分号,数据转换
*/
import SwiftUI
struct SwiftView01: View {
var result: String = "";
init() {
// print() - 在控制台打印数据
print("webabcd");
/*
/*
* 注释可嵌套
*/
*/
result = sample1(); // 变量和常量
result += "\n";
result += sample2(); // 基本数据类型
result += "\n";
result += sample3(); // 元组
result += "\n";
result += sample4(); // 可选类型(Optional),即可空类型
result += "\n";
result += sample5(); // 运算符
result += "\n";
result += sample6(); // 范围运算符(m...n,m...,...n,m..<n)
result += "\n";
result += sample7(); // 数据的类型转换
}
var body: some View {
VStack {
HStack {
Text(result)
Spacer()
}
Spacer()
}
}
func sample1() -> String {
var a = ""; // var - 变量
a = "a"
let b = "b"; // let - 常量(准确的说是不可变变量,即在运行时决定而不是编译时决定)
let 中文 = "c"; // 变量名支持任意 unicode 字符
let `var` = "d"; // 用 swift 的关键字做变量名的话要用 `` 包围起来
let e = "e", f = "f"; // 在一行里声明多个变量用 , 隔开
let g = "g" // 语句末尾可以不加分号(除非多条语句在同一行)
return a + b + 中文 + `var` + e + f + g; // abcdefg
}
func sample2() -> String {
// 支持 Int, Int64, UInt, UInt64, Float, Double, Bool, String, Character 等基本数据类型
let a: Int = 10; // 通过在变量名后面加上 :数据类型 来指定变量的数据类型(不指定的话则由编译器自己推断)
let b: Double = 10.0;
// var c = a + b; // 注意:swift 不支持数据类型的隐式转换,这句会编译时报错的
let c = Double(a) + b; // 需要对数据类型做强制转换
let d = 1.0; // 编译器会将数据类型推断为 double 而不是 float
let e = 0b11111111; // 二进制
let f = 0o377; // 八进制
let g = 0xff; // 十六进制
// e 跟在十进制数后面,代表 10 的 n 次方,结果是 double 类型,此句意为 123 乘以 10 的 3 次方
let h = 123e3;
// p 跟在二进制数后面,代表 2 的 n 次方,结果是 double 类型,此句意为 15 乘以 2 的 3 次方
let i = 0xfp3;
// 通过 _ 连接数字,以便阅读
let j = 12_345_67.1_23_4567;
// typealias - 为类型指定别名
typealias MyInt = Int;
let k: MyInt = 100;
// 10, 10.0, 20.0, 1.0, 255, 255, 255, 123000.0, 120.0, 1234567.1234567, 100
return "\(a), \(b), \(c), \(d), \(e), \(f), \(g), \(h), \(i), \(j), \(k)";
}
func sample3() -> String {
// 元组(Tuple)用于将多个值组成一个复合值
var a: (Int, Bool, String) = (1, true, "webabcd");
// 通过 .0 .1 .2 之类的访问元组中指定索引位置的元素
a.0 = 100;
// 元组分解,如果你不想用元组中的某些元素,就用 _ 代表他
let (b, c, _) = a;
// 元组定义时,可以指定每个元素的名称
var d = (p1:"v1", p2:"v2");
// 通过指定元素名称访问元组中的指定元素
d.p1 = "v100";
// 100, true, webabcd, 100, true, v100, v2
return "\(a.0), \(a.1), \(a.2), \(b), \(c), \(d.p1), \(d.p2)";
}
// 像下面这样写是会报错的,因为 aaa 没有初始化
// var aaa: MyClass
// 像下面这样写是不会报错的
// 类型后面跟 ? 用于声明可选类型(Optional),即可空类型
// 后续使用的时候,可以 bbb?.hello() 或 bbb!.hello()
var bbb: MyClass?
// 像下面这样写是不会报错的
// 类型后面跟 ! 用于声明可选类型(Optional),即可空类型,但是它可以在需要的时候将可空类型隐式转换为对应的不可空类型
// 后续使用的时候,可以 ccc?.hello() 或 ccc!.hello()
// 也可以直接 ccc.hello() 其逻辑与 ccc!.hello() 相同,这就实现了类似其他语言的延迟初始化的效果
var ccc: MyClass!
class MyClass {
func hello() {
print("hello")
}
}
func sample4() -> String {
// 类型后面跟 ? 用于声明可选类型(Optional),即可空类型
let a: Int? = nil;
let b: Int? = 100;
// 值后面跟 ! 用于强制取出可空类型中的值(关于值后面跟 ? 请参见 sample5)
// let a2 = a!; // 此句会运行时报错,因为 a 是 nil
let b2 = b!; // 此句运行正常,b2 会被推断为 Int 类型,而不是 Int? 类型
// 类型后面跟 ! 用于声明可选类型(Optional),即可空类型,但是它可以在需要的时候将可空类型隐式转换为对应的不可空类型
var c: Int! = nil // c 的类型是 Int?(这里 c 被声明为 Int! 类型,其本质其实还是 Int? 类型,但是在需要的时候可以隐式转换为 Int 类型)
c = 100
let c2: Int = c // c2 的类型是 Int(这里 c 的类型会由 Int? 隐式转换为 Int,如果 c 的值是 nil 则会报错)
let c3 = c + 0 // c3 的类型是 Int(这里 c 的类型会由 Int? 隐式转换为 Int,如果 c 的值是 nil 则会报错)
// 如下方式用于尝试取出可空类型中的值
if let d = b { // 可以取出可空类型 b 中的值,这里 d 会被推断为 Int 类型,而不是 Int? 类型
// nil, Optional(100), 100, Optional(100), 100, 100, 100
return "\(a), \(b), \(b2), \(c), \(c2), \(c3), \(d)";
} else { // 可空类型 b 是 nil
return "不会走到这里"
}
}
func sample5() -> String {
// 经典的 + - * / 之类的运算符都是支持的,三元运算符 ? : 也是支持的
// 但是 ++ 和 -- 都是不支持的
let a: Int? = nil;
// ?? 的意思是:左侧的数据是 nil 则返回右侧的值,否则返回左侧的值
let b: Int = a ?? 123;
let c: String? = "webabcd";
let d: String? = nil
// 值后面跟 ? 然后再调用属性或方法的意思如下
// 1、左侧不为 nil 则调用右侧的属性或方法,然后将结果转换为对应的可空类型
// 2、左侧为 nil 则忽略右侧调用的属性或方法,直接返回 nil
// c.count 这句会编译时报错(因为 c 是可空类型,后面要跟 ? 或 !)
// c?.count 的结果是 Optional(7)
// c!.count 的结果是 7
// d?.count 的结果是 nil
// d!.count 这句会运行时报错(因为 d 是 nil)
class MyClass {
var a: Int?
}
let e: MyClass? = MyClass()
e!.a = 123
let f = e!.a // 结果是 Optional(123),这个好理解
let g = e!.a! // 结果是 123,这个好理解
let h = (e!.a)! // 结果是 123,这个好理解
let i = e?.a // 结果是 Optional(123),这个好理解
let j = e?.a! // 结果是 Optional(123),这个不太好理解,这种情况如果你想强制取出可空类型中的值,请用下面的方式
let k = (e?.a)! // 结果是 123,这个好理解
// nil, 123, Optional(7), 7, nil, Optional(123), 123, 123, Optional(123), 123
return "\(a), \(b), \(c?.count), \(c!.count), \(d?.count), \(f), \(g), \(h), \(i), \(j), \(k)";
}
func sample6() -> String {
let a = ["a", "b", "c", "d", "e", "f", "g"];
// 索引位置 2 到末尾
let b = a[2...]; // ["c", "d", "e", "f", "g"]
// 索引位置起始到 2
let c = a[...2]; // ["a", "b", "c"]
// 索引位置 2 到 4
let d = a[2...4]; // ["c", "d", "e"]
// 索引位置 2 到 3
let e = a[2..<4]; // ["c", "d"]
return "\(a), \(b), \(c), \(d), \(e)";
}
func sample7() -> String {
// 以下演示如何做数据的类型转换(注:Swift 是不支持数据类型的隐式转换的)
let a = "123"; // String 类型
let b = Int(123) // Int 类型
let c = [1, 2, 3] // Array<Int> 类型
let d = Set(c) // Set<Int> 类型
let e = Array(d) // Array<Int> 类型
let f = Array<Int>(d) // Array<Int> 类型
let g = [Int](d) // Array<Int> 类型
return "\(type(of: a)), \(type(of: b)), \(type(of: c)), \(type(of: d)), \(type(of: e)), \(type(of: f)), \(type(of: g))";
}
}