如何删除 Swift 中的可选字符串字符

76

如何去除可选字符


let color = colorChoiceSegmentedControl.titleForSegmentAtIndex(colorChoiceSegmentedControl.selectedSegmentIndex)

println(color) // Optional("Red")

let imageURLString = "http://hahaha.com/ha.php?color=\(color)"
println(imageURLString)
//http://hahaha.com/ha.php?color=Optional("Red")

我只想输出 "http://hahaha.com/ha.php?color=Red",应该怎么做呢?

嗯......

14个回答

118

实际上,当您将任何变量定义为可选类型时,您需要对该可选值进行解包。要解决此问题,您可以将变量声明为非可选类型,或在变量后加上!(感叹号)标记以解包可选值。

var optionalVariable : String? // This is an optional.
optionalVariable = "I am a programer"
print(optionalVariable) // Optional("I am a programer")
        
var nonOptionalVariable : String // This is not optional.
nonOptionalVariable = "I am a programer"
print(nonOptionalVariable) // "I am a programer"

//There are different ways to unwrap optional varialble

// 1 (Using if let or if var)
if let optionalVariable1 = optionalVariable {
    print(optionalVariable1)
}

// 2 (Using guard let or guard var)
guard let optionalVariable2 = optionalVariable else {
    fatalError()
}
print(optionalVariable2)

// 3 (Using default value ?? )
print(optionalVariable ?? "default value") // If variable is empty it will return default value

// 4 (Using force caste !)
print(optionalVariable!) // This is unsafe way and may lead to crash

2
我知道这是一个旧帖子,但我想澄清一些问题,以便如果有人现在看到它,他们会得到正确的信息。首先,println并不是print;其次,行变量temp1: String!不需要!,您只需编写var temp1:String // 这不是可选项。另外,在temp示例中,您可以通过编写print(temp!)而不必使用Optional()来打印temp的值//“我是程序员”,当然,如果temp的值为nil,则使用!将导致错误,因此最好使用if let或guard保护您的代码免受nil的影响。 - Mark Dail
1
这不是可选项。错了,它是一个“隐式解包可选项(IUO)”。当访问时,其值会自动解包。如果为nil,则应用程序将崩溃。 - Eric Aya
@Moritz 请查看问题。这不是关于崩溃的问题。 - Rajesh Maurya
我知道这个问题是关于什么的,哈哈。我告诉你的是,你所说的是错误的。你说“这不是可选项”的那一行是错的,这是一个可选项,它是一个隐式解包的可选项。 - Eric Aya

56

我再次查看了一遍,我正在简化我的答案。我认为这里的大多数答案都没有抓住重点。通常您希望打印变量是否具有值,而且如果变量没有值,则希望程序不会崩溃(因此不要使用!)。在这里只需执行此操作:

    print("color: \(color ?? "")")

这将给你一个空值或者该值。


25
你需要在通过字符串插值使用之前取消可选项的包装。最安全的方法是通过可选绑定来实现:
if let color = colorChoiceSegmentedControl.titleForSegmentAtIndex(colorChoiceSegmentedControl.selectedSegmentIndex) {
    println(color) // "Red"

    let imageURLString = "http://hahaha.com/ha.php?color=\(color)"
    println(imageURLString) // http://hahaha.com/ha.php?color=Red
}

@user1272854 我回答中的代码应该可以实现你想要的功能。你发布在问题中的代码与此有所不同吗? - Mike S

12
Swift3中,您可以轻松地删除可选项。
if let value = optionalvariable{
 //in value you will get non optional value
}

1
我喜欢这个。虽然涉及到更多的代码,但它是安全的,干净的,并且,你可以在可选项为nil时执行操作,而无需在其他地方检查它。 - Septronic
哈哈,我一直在经常使用它,但实际上并不知道它是做什么的。现在我特别需要它,但不知道如何搜索它:D 非常感谢,@MaciejSwic,这就是应该做的方式。 - user2875404

11

检查是否为nil并使用"!"进行解包:

let color = colorChoiceSegmentedControl.titleForSegmentAtIndex(colorChoiceSegmentedControl.selectedSegmentIndex)

println(color) // Optional("Red")

if color != nil {
    println(color!) // "Red"
    let imageURLString = "http://hahaha.com/ha.php?color=\(color!)"
    println(imageURLString)
    //"http://hahaha.com/ha.php?color=Red"
}

1
这个可以用,但强制解包可选项真的是一个很糟糕的实践。你抛弃了 Swift 赋予你的所有类型安全性。使用 if letguard 来绑定可选项到一个常量变量。(见 Mike 的回答) - Kevin

6
除了其他答案提到的解决方案,如果您想始终避免整个项目中出现Optional文本,您可以添加此pod:
pod 'NoOptionalInterpolation'

(https://github.com/T-Pham/NoOptionalInterpolation)

该pod添加了一个扩展,用于覆盖字符串插值init方法,以一劳永逸地摆脱可选文本。它还提供了一个自定义运算符*,可以恢复默认行为。

所以:

import NoOptionalInterpolation
let a: String? = "string"
"\(a)"  // string
"\(a*)" // Optional("string")

请查看此答案https://dev59.com/oYPba4cB1Zd3GeqPqElp#37481627以获取更多详细信息。

4

试试这个:

var check:String?="optional String"
print(check!) //optional string. This will result in nil while unwrapping an optional value if value is not initialized or if initialized to nil.
print(check) //Optional("optional string") //nil values are handled in this statement

如果你确信变量中不会有nil,那么请使用first。同时,你也可以使用if let或Guard let语句在不发生任何崩溃的情况下解包可选项。

 if let unwrapperStr = check
 {
    print(unwrapperStr) //optional String
 }

Guard let,

 guard let gUnwrap = check else
 {
    //handle failed unwrap case here
 }
 print(gUnwrap) //optional String

1
这并不完全正确。在第一个例子中,如果你使用print(check!)而对象实际上是nil,它将会导致你的应用程序崩溃。添加一个感叹号将可选项从String?更改为String。如果它是nil,那么这将失败并导致崩溃。 - Matthew Knippen
人们需要停止滥用!运算符。可选项的存在是因为可选项的概念是您希望允许变量可能为空值的可能性。就像@MatthewKnippen所说,如果您强制解包一个空值的可选项,那么应用程序将崩溃。如果您需要强制解包可选项,那么您可能不应该使用可选项。至少,您应该使用if letguard let else解包以确保它不为空。 - Clayton C.

1
简单地将代码中的?替换为!解决了我的问题。
usernameLabel.text = "\(userInfo?.userName)"

To

usernameLabel.text = "\(userInfo!.userName)"

1
尽管我们可能有不同的上下文,但以下内容对我有效。
我用括号包含变量的每个部分,然后在右括号外添加一个感叹号。
例如,print(documentData["mileage"]) 改为:
print((documentData["mileage"])!)

0

如何在Swift UIkit中删除可选字符串字符以进行打印

从这些(具有可选打印)

print("Collection Cell \(categories[indexPath.row].title) \(indexPath.row)")

对于这些(没有可选的打印)

print("Collection Cell \(categories[indexPath.row].title ?? "default value") \(indexPath.row)")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接