在可选项中包装swift变量的简写?

Sen*_*ful 6 variables syntax casting optional swift

Swift允许我们使用简写符号str!来打开可选项.但是,如果我们想做相反的事情呢?

说我有一个变量:

var str = String() // String
Run Code Online (Sandbox Code Playgroud)

是否有任何简写符号将其转换为可选(即String?String!)?

(例如,我想做类似的事情var strOptional = ?(str).)

或者,如果没有这种表示法的简写,如何将其转换为可选项而不明确提及其类型(例如我不想提及String).

换句话说,我知道我可以使用以下任何方法将变量包装为可选:

var strOptional = str as String?
var strOptional: String? = str
var strOptional = String?(str)
Run Code Online (Sandbox Code Playgroud)

......但在每种情况下,我都必须明确写出来String.

var strOptional = str as typeof?(str)如果没有简写语法,我宁愿写一些类似于:(优点是如果变量的类型在代码库中经常更改,那么更新的位置就会少一些.)


至于这个有用的实际示例,想象一下我想使用AVCaptureDevice并使用以下代码:

let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
device.lockForConfiguration(nil)
Run Code Online (Sandbox Code Playgroud)

lockForConfiguration()将在没有摄像机的设备上运行时崩溃,编译器不会警告我.原因是defaultDeviceWithMediaType可以nil根据文档[1]返回,但它被定义为返回a AVCaptureDevice!.

要修复这样的错误API,最好做以下事情:

let device = ?(AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo))
Run Code Online (Sandbox Code Playgroud)

...得到一个AVCaptureDevice?,并让编译器捕获我可能犯的任何错误.

目前,我必须诉诸于更加冗长:

let device: AVCaptureDevice? = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
Run Code Online (Sandbox Code Playgroud)

另一个例子:

在这种情况下,我想为我的变量提供一个默认值,这是一个字符串,但稍后,我可能想为它nil赋值.

var myString = "Hi"
// ...
if (someCondition()) {
    myString = nil // Syntax error: myString is String
}
Run Code Online (Sandbox Code Playgroud)

目前我不得不诉诸,var myString: String? = "Hi"var myString = ?("Hi")不那么冗长.


[1]如果打开AVCaptureDevice.h,您将看到有关返回值的以下文档:"具有给定媒体类型的默认设备,如果不存在具有该媒体类型的设备,则为nil."

ABa*_*ith 0

要包装变量,您可以使用运算符重载和泛型函数。例如:

prefix operator ??? {}

prefix func ??? <T> (x: T) -> T? {
    return Optional(x)
}
Run Code Online (Sandbox Code Playgroud)

要将其与第二个示例相关联,您将执行以下操作:

var myString = ???"Hi" // Optional("Hi")

if someCondition() {
    myString = nil
}
Run Code Online (Sandbox Code Playgroud)