面试题答案
一键面试存储属性
- 结构体:结构体是值类型,它的实例在被传递或赋值时,会进行值拷贝。每个实例都有自己独立的存储属性副本。例如:
struct Point {
var x: Int
var y: Int
}
var point1 = Point(x: 10, y: 20)
var point2 = point1
point2.x = 30
print(point1.x) // 输出 10,说明 point1 和 point2 是不同的副本
- 类:类是引用类型,类的实例在被传递或赋值时,传递的是引用(内存地址),多个变量可以引用同一个实例,共享存储属性。例如:
class Rectangle {
var width: Int
var height: Int
init(width: Int, height: Int) {
self.width = width
self.height = height
}
}
var rect1 = Rectangle(width: 100, height: 200)
var rect2 = rect1
rect2.width = 150
print(rect1.width) // 输出 150,说明 rect1 和 rect2 引用同一个实例
引用方式
- 结构体:结构体的值拷贝特性使得它在函数参数传递、赋值等操作时,都是传递完整的值,适用于数据量较小、希望数据独立的场景。例如,函数接收一个结构体参数时,函数内部对参数的修改不会影响外部的原始实例。
struct Size {
var width: Double
var height: Double
}
func modifySize(_ size: Size) {
var localSize = size
localSize.width = 50.0
localSize.height = 50.0
}
var mySize = Size(width: 100.0, height: 100.0)
modifySize(mySize)
print(mySize.width) // 输出 100.0,mySize 未被修改
- 类:类的引用特性使得在函数参数传递、赋值等操作时,传递的是引用,适用于数据量较大、希望共享数据的场景。例如,函数接收一个类的实例作为参数时,函数内部对实例属性的修改会影响外部的原始实例。
class Circle {
var radius: Double
init(radius: Double) {
self.radius = radius
}
}
func modifyCircle(_ circle: Circle) {
circle.radius = 10.0
}
var myCircle = Circle(radius: 5.0)
modifyCircle(myCircle)
print(myCircle.radius) // 输出 10.0,myCircle 被修改
初始化过程
- 结构体:结构体有默认的成员逐一初始化器,即使没有显式定义初始化器,也可以通过成员逐一初始化器来初始化实例。例如:
struct Color {
var red: Int
var green: Int
var blue: Int
}
let myColor = Color(red: 255, green: 0, blue: 0) // 使用默认的成员逐一初始化器
结构体也可以自定义初始化器,并且在自定义初始化器中,必须确保所有存储属性都被初始化。
struct Rectangle {
var width: Int
var height: Int
init(sideLength: Int) {
width = sideLength
height = sideLength
}
}
let square = Rectangle(sideLength: 5)
- 类:类必须为所有存储属性提供初始值,可以在属性声明处提供默认值,也可以在初始化器中进行初始化。类有指定初始化器和便利初始化器,指定初始化器必须调用其直接父类的指定初始化器,以确保父类的所有属性也被正确初始化。例如:
class Animal {
var name: String
init(name: String) {
self.name = name
}
}
class Dog: Animal {
var breed: String
init(name: String, breed: String) {
self.breed = breed
super.init(name: name)
}
}
let myDog = Dog(name: "Buddy", breed: "Labrador")
便利初始化器必须调用同一个类的另一个初始化器,最终也会调用到指定初始化器。例如:
class Dog {
var name: String
var breed: String
init(name: String, breed: String) {
self.name = name
self.breed = breed
}
convenience init() {
self.init(name: "Unknown", breed: "Unknown")
}
}
let defaultDog = Dog()