IOS面试题——Swift方法、闭包(4)

一 面试题汇总

  1. 实例方法和类方法有什么区别?
  2. 值类型的属性想要被自身的实例方法修改,怎么实现?mutating
  3. 什么是闭包?闭包表达式是怎么样的?
  4. 闭包作为参数时的缩写?什么是尾随闭包?
  5. @autoclosure是什么?有什么作用?
  6. Swift函数定义,函数重载,函数类型

二 面试题解答(仅供参考)

2.1 实例方法和类方法有什么区别?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
在Swift中,实例方法(Instance Methods)和类方法(Class Methods)是两种不同类型的方法,它们有以下区别:

1-实例方法(Instance Methods):
1.1-属于实例:实例方法属于类、结构体或枚举的实例,只能通过实例来调用。
1.2-访问实例属性:实例方法可以访问和修改实例的属性,并且可以调用其他实例方法。
1.3-self关键字:在实例方法中,可以使用 self 关键字来引用实例本身。
1.4-动态分派:实例方法在运行时动态分派,意味着调用的方法取决于实例的类型。

2-类方法(Class Methods):
2.1-属于类型:类方法属于类本身,而不是类的实例。可以通过类名直接调用,而不需要创建类的实例。
2.2-访问类属性:类方法可以访问和修改类的属性,并且可以调用其他类方法。
2.3-不需要实例化:类方法不依赖于任何特定的实例,因此在调用时不需要创建类的实例。
2.4-不能访问实例属性:类方法不能访问实例属性,因为它们不依赖于实例。

3-使用场景:

3.1-实例方法通常用于操作特定实例的状态或数据,并且可能依赖于实例的属性值。
3.2-类方法通常用于执行与类相关的功能,而不需要特定的实例,例如工具方法或者工厂方法。

总的来说,实例方法是操作实例的方法,而类方法是操作类本身的方法。
你应该根据需要选择使用哪种类型的方法。

2.2 值类型的属性想要被自身的实例方法修改,怎么实现?mutating

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
如果你想要在值类型(如结构体或枚举)的实例方法中修改属性的值,你需要将该方法标记为 mutating。
通过使用 mutating 关键字,你可以告诉编译器该方法可以修改结构体或枚举的实例属性。

下面是一个示例,演示了如何在结构体的实例方法中修改属性的值:

struct MyStruct {
var value: Int

// 将方法标记为 mutating,以允许修改属性
mutating func modifyValue(newValue: Int) {
self.value = newValue
}
}

var myInstance = MyStruct(value: 10)
print(myInstance.value) // 输出:10

// 调用实例方法修改属性值
myInstance.modifyValue(newValue: 20)
print(myInstance.value) // 输出:20

在这个例子中,modifyValue 方法被标记为 mutating,
因此可以在方法内部修改 MyStruct 实例的属性 value。
在调用该方法时,实例方法会改变其调用者的属性值。

总之,如果你需要在值类型的实例方法中修改属性的值,记得将方法标记为 mutating。

2.3 什么是闭包?闭包表达式是怎么样的?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
在 Swift 中,闭包是一个自包含的函数代码块,可以在代码中被传递和使用,
就像其他类型的数据(比如字符串和整数)一样。
闭包可以捕获并存储其所在上下文中任意常量和变量的引用,这也被称为闭包的"捕获值"。
闭包可以作为参数传递给函数,也可以从函数中返回,并且可以在代码中嵌套定义。

闭包表达式是一种轻量级的语法,用于编写内联的匿名函数或闭包。
它们采用了一种简洁的语法形式,使得在代码中定义和使用闭包变得更加方便和直观。

闭包表达式的基本语法:
闭包表达式的基本语法形式如下:

{ (parameters) -> returnType in
statements
}
1-{} 包裹起闭包的代码块。
2-parameters 定义了闭包的参数列表,可以是空的,也可以包含一个或多个参数,参数之间用逗号分隔。
3-returnType 定义了闭包的返回类型,可以是实际类型或者 Void。
4-in 关键字标识了闭包的参数列表和返回类型与闭包体之间的分隔。
5-statements 包含了闭包的执行语句,即闭包体。

2.4 闭包作为参数时的缩写?什么是尾随闭包?

1
2
3
4
5
6
7
8
9
10
11
在 Swift 中,闭包可以作为函数的参数传递,而且由于闭包表达式的简洁性,通常可以使用一种被称为“尾随闭包”的语法来传递闭包参数。

1-闭包作为参数时的缩写:
当闭包作为函数的最后一个参数时,你可以使用闭包表达式的缩写形式,
省略掉参数和返回值类型,以及 in 关键字。
在这种情况下,闭包表达式直接放在函数调用的括号外面,并用大括号包裹起来。

2-尾随闭包(Trailing Closures):
尾随闭包是一种特殊的语法,用于在函数调用的括号之后传递闭包参数。
如果闭包是函数的最后一个参数,你可以将闭包表达式写在函数调用的括号外,
并且省略掉参数标签,直接用大括号包裹起来。

2.5 @autoclosure是什么?有什么作用?

1
2
3
4
5
6
7
8
@autoclosure 是一个属性包装器,它用于延迟求值表达式,将表达式自动封装成闭包。
当你将一个被 @autoclosure 标记的参数传递给一个函数时,
参数的表达式将不会被提前计算,而是在函数内部按需求值求值。

@autoclosure 的作用在于简化函数的调用和提高性能。
它特别适用于那些需要延迟执行的参数,以避免不必要的计算。
通常情况下,你可能会手动将表达式封装成闭包并传递给函数,
而使用 @autoclosure 可以使语法更加简洁,同时不影响代码的可读性。

2.6 Swift函数定义,函数重载,函数类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
在 Swift 中,函数是一段完成特定任务的独立代码块,它可以接受零个或多个参数,并且可以返回一个值。
函数可以通过函数名来调用,并且可以在代码中被多次调用。

1-函数定义:
下面是一个简单的函数定义示例:

func greet(person: String) -> String {
return "Hello, \(person)!"
}

let greeting = greet(person: "Alice")
print(greeting) // 输出:Hello, Alice!

在这个示例中,greet 是一个函数,它接受一个名为 person 的参数,返回一个字符串。
函数的参数和返回值通过箭头 -> 来指定。

2-函数重载:
函数重载是指在同一个作用域内,可以定义多个同名的函数,但参数的数量或类型必须不同。
这样做可以使你在相同的上下文中使用同一个函数名来执行不同的操作。

func add(a: Int, b: Int) -> Int {
return a + b
}

func add(a: Double, b: Double) -> Double {
return a + b
}

在这个示例中,add 函数被重载了两次,分别接受两个 Int 类型的参数和两个 Double 类型的参数。

3-函数类型:
在 Swift 中,函数也是一种类型,可以作为函数的参数或返回值。
函数类型由其参数类型和返回类型组成,包括参数列表和返回类型。
函数类型可以使用 (参数类型) -> 返回类型 的形式来表示。

func greet(person: String) -> String {
return "Hello, \(person)!"
}

var function: (String) -> String = greet

在这个示例中,function 是一个函数类型的变量,
它可以存储任何接受一个 String 类型参数并返回一个 String 类型值的函数。
这里将 greet 函数赋值给了 function 变量,因为它符合该函数类型的定义。

三 参考

  • 简书—swift方法、闭包