每次打开Xcode准备写Swift代码时,总有种打开新世界大门的感觉。这门语言就像苹果工程师精心调制的鸡尾酒,混合了现代编程语言的精华,又保留了独特的果香。
变量与常量的声明与使用
在Swift里区分变量和常量特别简单 - 就像区分会变心的恋人和忠贞不渝的朋友。用var
声明变量,这个值以后还能改;用let
声明常量,一旦确定就至死不渝。有趣的是,Swift官方文档居然建议我们优先使用常量,这大概是在教我们对待数据要专一?
var changeable = "我可以被改变"
let constant = "我永远不变"
Xcode有个贴心的小功能,如果你试图修改一个常量,它会立即用红色波浪线提醒你:"嘿,说好不变的!"这种设计让我想起妈妈总在我偷吃零食时的眼神。
基本数据类型详解
Swift的数据类型家族相当丰富,从简单的Int、Double到复杂的元组,每个成员都有自己的个性。Int类型会根据设备自动选择32位或64位,就像会自己调节大小的智能衣服。Double和Float的区别就像是专业相机和手机摄像头 - 一个精度高,一个省内存。
字符串处理是Swift的强项,三引号"""可以创建多行字符串,写首诗都不用换行符了。有时候我会对着字符串插值功能傻笑,在引号里直接放变量这种操作,简直像变魔术。
let poem = """
春眠不觉晓,
处处闻啼鸟。
"""
let score = 95
print("我的分数是:\(score)")
运算符与表达式
Swift的运算符就像瑞士军刀,功能齐全还带些特殊装备。除了常规的加减乘除,区间运算符"..."和"..<"特别有意思,写循环时再也不用纠结边界条件了。
比较运算符返回的是Bool类型,这让我想起小时候非黑即白的思维方式。而三元运算符就像是代码里的快问快答:"成绩及格了吗?打印'通过',否则打印'重考'"。
1...5 // 1到5
1..<5 // 1到4
let result = score >= 60 ? "通过" : "重考"
有时候我会想,为什么Swift没有自增++运算符?后来明白这是为了代码更清晰。看来苹果工程师们不仅是技术专家,还是代码美学主义者啊。
写Swift代码就像在指挥一支交响乐团,控制流就是我的指挥棒,而数据结构则是各种乐器。当它们完美配合时,就能演奏出优雅的程序乐章。
条件语句与循环结构
if语句在Swift里变得特别清爽,条件表达式不再需要括号包裹,就像脱掉了厚重的外套。switch语句则像个多才多艺的杂技演员,不仅能匹配各种情况,还能处理区间匹配和元组匹配。
let weather = "sunny"
switch weather {
case "rainy":
print("记得带伞")
case "sunny", "cloudy":
print("适合出门")
default:
print("天气未知")
}
循环结构就像永动机,for-in循环尤其擅长遍历集合。当我在代码里写下for number in 1...5
时,仿佛看到五个小数字排着队从我面前走过。while循环则像个固执的小孩,不满足条件绝不罢休。
数组和字典的使用
数组就像整齐的储物柜,每个物品都有自己的编号位置。Swift的数组特别聪明,它能自动推断元素类型,还能用简洁的语法进行增删改查。第一次用append()
方法时,我感觉像是在往魔法袋里不断塞东西却永远不会满。
var shoppingList = ["鸡蛋", "牛奶"]
shoppingList += ["面包"]
shoppingList[1] = "酸奶"
字典则是更随性的收纳达人,用键值对存储数据。查找字典就像玩寻宝游戏,给出正确的钥匙就能找到对应的宝藏。当我在代码中写下let age = people["Alice"]
时,总有种在人群中喊人名字的错觉。
元组的特性与应用
元组是Swift里的百变星君,能临时组合不同类型的数据。处理函数多返回值时,元组就像个轻便的快递盒,把各种数据打包一起送回。解构元组时特别有趣,仿佛在拆解一个精致的俄罗斯套娃。
let httpStatus = (code: 404, message: "Not Found")
print(httpStatus.code) // 像访问对象属性一样自然
有时候我会用元组来交换两个变量的值,一行代码(a, b) = (b, a)
就搞定,比用临时变量优雅多了。这让我想起魔术师的手法,眨眼间就完成了不可思议的交换。
写Swift代码就像在建造一座城市,函数是城市里的各种功能建筑,而面向对象编程则是城市规划蓝图。当它们协同工作时,整个城市就变得井然有序又充满活力。
函数的定义与调用
在Swift里定义函数就像写一首小诗,参数列表清晰得像诗句的韵律。每个函数都有明确的返回值类型,就像诗人知道这首诗要表达什么情感。第一次用参数标签时,感觉像是在给函数参数戴上了姓名牌。
func bakeCookie(for person: String, count: Int) -> String {
return "给\(person)烤了\(count)块饼干"
}
let message = bakeCookie(for: "小明", count: 3)
函数参数可以有默认值,这让我想起餐厅的点单系统——"您要加冰吗?默认是不加"。可变参数则像个贪吃蛇,能吞下任意数量的同类型参数。inout参数特别神奇,能让函数直接修改外部变量,就像给了函数一把钥匙来开你家的门。
闭包的使用场景
闭包是Swift里的匿名信使,能带着代码到处跑。排序数组时用闭包,就像在教编译器怎么比较两个元素的大小。网络请求完成时的回调闭包,则像个耐心的邮差,等数据到了就立刻送上门。
let names = ["Chris", "Alex", "Ewa"]
let reversedNames = names.sorted { $0 > $1 }
逃逸闭包特别有意思,它能在函数返回后继续存活,像个偷偷溜出家门的小孩。自动闭包则像个懒散的助手,直到最后一刻才执行任务。写闭包时经常用类型推断和隐式返回,代码变得像电报一样简洁。
类与对象的基本概念
定义类就像设计一个机器人图纸,属性是它的零件,方法是它能做的事情。实例化对象时,感觉像是从图纸里真的造出了机器人。每次调用对象方法,都像在给机器人下达指令。
class CoffeeMaker {
var beansCount = 0
func fillBeans(count: Int) {
beansCount += count
print("现在有\(beansCount)克咖啡豆")
}
}
let myMaker = CoffeeMaker()
myMaker.fillBeans(count: 20)
属性观察器willSet和didSet像是安在属性上的监控摄像头,数值变化时立即报警。计算属性则像个精明的会计,每次访问都重新算账。懒加载属性最会偷懒,直到被用到时才肯工作。
继承与多态的实现
继承关系就像家族族谱,子类自动获得父类的特征。重写方法时要用override关键字,像是在说"老爸的方法不错,但我想做得更好"。多态让不同子类对象对同一方法调用产生不同反应,就像不同乐器演奏同一个音符。
class Animal {
func makeSound() {
print("某种动物叫声")
}
}
class Cat: Animal {
override func makeSound() {
print("喵喵喵")
}
}
let pets: [Animal] = [Animal(), Cat()]
for pet in pets {
pet.makeSound() // 同一个调用,不同表现
}
类型检查is和类型转换as?像是给对象做DNA检测。协议让不同类型能遵守相同规范,就像不同职业的人都必须遵守交通规则。看到自己的类层次结构越来越丰富时,感觉像是在培育一个数字生物族群。
Swift就像一位魔术师,总能在关键时刻变出令人惊喜的特性。这些高级语法特性让代码不仅更安全,还像乐高积木一样灵活组合。每次发现新特性时,都感觉像是找到了编程工具箱里的隐藏工具。
可选类型的处理机制
可选类型是Swift的安全气囊,防止你一头撞上空值。第一次看到String?时,还以为键盘打错了符号。实际上那个问号在说"这里可能有值,也可能什么都没有"。强制解包就像拆炸弹,用!时要确保万无一失。
var optionalName: String? = "张三"
print(optionalName!) // 自信地拆开礼物
var nilName: String? = nil
// print(nilName!) // 这会爆炸
可选绑定是更优雅的方式,像在说"如果有值,我们就用;没有就算了"。guard let像是门卫,不满足条件就请出门右转。可选链式调用特别聪明,遇到nil就默默停止,不会半路崩溃。
if let name = optionalName {
print("名字是\(name)")
} else {
print("没有名字")
}
func greet(_ name: String?) {
guard let unwrappedName = name else {
print("访客您好")
return
}
print("\(unwrappedName)您好")
}
错误处理的最佳实践
Swift的错误处理像在玩抛接球游戏,函数抛出错误,调用者负责接住。定义错误枚举时,感觉像是在编写错误词典。throws关键字像是给函数贴了个警告标签:"我可能会发脾气"。
enum VendingMachineError: Error {
case invalidSelection
case insufficientFunds(coinsNeeded: Int)
case outOfStock
}
func buySnack() throws {
throw VendingMachineError.insufficientFunds(coinsNeeded: 5)
}
do-catch块像错误处理的安全网,尝试执行可能出错的代码。try?让错误变成可选值,失败就返回nil。try!则是霸王硬上弓,确信不会出错时才敢用。defer语句特别贴心,无论成功失败都会执行清理工作。
do {
try buySnack()
} catch VendingMachineError.insufficientFunds(let coinsNeeded) {
print("还差\(coinsNeeded)个硬币")
} catch {
print("其他错误: \(error)")
}
let result = try? buySnack() // 安全尝试
泛型编程基础
泛型是代码界的变形金刚,能适应各种类型需求。第一次写
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
var num1 = 100, num2 = 200
swapTwoValues(&num1, &num2)
var str1 = "hello", str2 = "world"
swapTwoValues(&str1, &str2)
泛型类型更加强大,比如Array和Dictionary都是泛型集合。关联类型让协议也能玩泛型,where子句则像给泛型添加约束条件。看到泛型代码时,总想起那句"一次编写,到处使用"。
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
var stringStack = Stack<String>()
stringStack.push("苹果")
stringStack.push("香蕉")
Swift与Objective-C语法对比
从Objective-C转到Swift,就像从手动挡换到自动挡。方括号调用变成了点语法,消息发送机制变成了直接方法调用。看到@objc标记时,感觉像是在两种语言之间架桥。
// Objective-C风格
// [myObject doSomethingWith:param1 and:param2];
// Swift风格
myObject.doSomething(with: param1, and: param2)
可选类型取代了nil检查,guard语句替代了冗长的if嵌套。Swift的闭包比Objective-C的block更简洁安全,类型推断让代码不再充满类型声明。协议扩展让Swift协议比Objective-C协议强大得多,就像给协议装上了火箭推进器。
// Objective-C的block
// void (^block)(void) = ^{ NSLog(@"Hello"); };
// Swift的闭包
let closure = { print("Hello") }
每次对比两种语法,都庆幸Swift让iOS开发变得如此优雅。不过在某些需要与Objective-C交互的场景,还是得穿上"兼容性外套",用@objc标记必要的属性和方法。这种双语切换能力,倒像是掌握了编程世界的双语优势。
标签: #Swift变量与常量 #Swift数据类型详解 #Swift闭包使用 #Swift类与对象 #Swift错误处理