Swift 类型推断需要问号或感叹号
Posted
技术标签:
【中文标题】Swift 类型推断需要问号或感叹号【英文标题】:Swift Type Inference requires question mark or exclamation point 【发布时间】:2017-01-02 21:33:47 【问题描述】:阅读 Apple 的 ARC 指南后,我正在慢慢尝试掌握保留周期,但我不清楚的是 swift 的类型推断在推断全局变量时需要可选问号或强制展开感叹号类的范围。
例如:
import XCTest
@testable import PassionProject
class ItemManagerTests: XCTestCase
var sut: ItemManager!
override func setUp()
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
sut = ItemManager()
override func tearDown()
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
func tests_ToDoCount_Is_InitiallyZero()
XCTAssertEqual(sut.toDoCount, 0)
func tests_DoneCount_Is_InitiallyZero()
XCTAssertEqual(sut.doneCount, 0)
如果我在下一行省略了问号或解释点,则会引发关于类没有初始化器的错误:
var sut: ItemManager
我的问题是,类型推断不只是简单地说这个变量将是这种类型吗?如果是这样,如果我们没有给它一个初始值,为什么 Xcode 会认为它是一个属性?其次,如果我们从未设置推断类型的值,为什么要强制解包它?
如果需要,这里是我们用作示例的对象的代码,并提前感谢您更好地掌握:
import Foundation
class ItemManager
let toDoCount = 0
let doneCount = 0
【问题讨论】:
【参考方案1】:这不是类型推断。如果你声明一个变量的类型,推理就不会发生。推理就是弄清楚(推断)一个类型是什么如果你没有明确说明。
您遇到了 Swift 初始化规则的问题。如果你声明一个类有这个属性:
var sut: ItemManager
那么这是非可选的,这意味着在初始化完成时它必须有一个值。你没有这样做,所以 Swift 抱怨你的初始化器。您可以添加一个分配值的init
方法,也可以同时声明它并分配一个值——可能如下所示:
var sut: ItemManager = ItemManager()
如果你这样声明:
var sut: ItemManager?
那么它是可选的,这意味着如果你不赋值,那么它的值就是 nil。您不必在初始化期间分配一个值,因为它已经有一个。
【讨论】:
在分配时不要明确说明类型。让推理发挥作用:var sut = ItemManager()
【参考方案2】:
出于安全原因,Swift 要求所有变量始终保持一个值。这可以防止出现变量值未知的情况。但是,在编程中仍然存在想要表示缺少值的情况。执行搜索时就是一个很好的例子。人们希望能够从搜索中返回一些表明没有找到值的东西。
因此,在 Swift 中,类成员在声明时必须有一个值。默认情况下,特定类型的成员,例如 Int 不能为 nil,它不会获得默认值。如果我们知道该值一个变量的值可能为 nil,然后我们将其定义为 Optional。
现在您有三个选项可以为类成员提供初始值:
通过在声明时初始化
通过在 init 方法中为其提供一个值
通过将其定义为可选或未包装的可选,这取决于变量的使用
【讨论】:
以上是关于Swift 类型推断需要问号或感叹号的主要内容,如果未能解决你的问题,请参考以下文章
推断常量 'spacesLeft' 具有类型 '()',这可能是 Swift 的意外