【问题标题】:Unwrap an Optional Within a Multiple Parameter Function在多参数函数中展开可选项
【发布时间】:2016-01-27 00:57:10
【问题描述】:

这个问题可能看起来很基础,但我试图在下面的代码中解开middleName 可选参数。我已经在这里成功解开了可选的返回,但我仍然收到Matthew Optional("Matt") Stevenson 记录。如何打开“Matt”并删除可选的返回?

func returnFullName (name: (firstName: String, middleName: String?,
                    lastName: String)) -> String? 
    {
    return ("\(name.firstName) \(name.middleName) \(name.lastName)")
}

var fullName = returnFullName(("Matthew", middleName: "Matt", lastName: "Stevenson"))

if let printFullName = fullName {
    print (printFullName)
}

【问题讨论】:

  • 我将不得不开始给我的朋友 Matthew Optional("Matt") 简称。有一个不错的戒指。

标签: swift function optional-parameters


【解决方案1】:

您可以将nil coalescing operator 用于可选的middleName 属性。如果值为nil,则将打印默认的"",而如果该值包含非零字符串,则将其解包。

return ("\(name.firstName) \(name.middleName ?? "") \(name.lastName)")

但是请注意,您不必让 returnFullName(..) 函数的返回类型是可选的,因为该值永远不会为零。

func returnFullName (name: (firstName: String, middleName: String?,
    lastName: String)) -> String {
    return ("\(name.firstName) \(name.middleName ?? "") \(name.lastName)")
}

print(returnFullName(("Matthew", middleName: "Matt", lastName: "Stevenson"))) 
    // Matthew Matt Stevenson
print(returnFullName(("Matthew", middleName: nil, lastName: "Stevenson")))    
    // Matthew  Stevenson   <-- extra unwanted space 

另外,我没有看到任何明显的理由在函数签名中使用元组,而不是为不同的名称组件单独参数。因此,一个替代方案如下:

func returnFullName (firstName: String, middleName: String?,
    lastName: String) -> String {
    return "\(firstName) \(middleName ?? "") \(lastName)"
}

print(returnFullName("Matthew", middleName: "Matt", lastName: "Stevenson")) 
    // Matthew Matt Stevenson
print(returnFullName("Matthew", middleName: nil, lastName: "Stevenson"))    
    // Matthew  Stevenson   <-- extra unwanted space

最后,为了避免nil-valued middleName 的额外空间,我建议保留单行返回,而是使用带有if let - else 子句的可选绑定:

func returnFullName(firstName: String, middleName: String?, lastName: String) -> String {
    if let middleName = middleName {
        return ("\(firstName) \(middleName) \(lastName)")
    }
    else {
        return ("\(firstName) \(lastName)")
    }
}

print(returnFullName("Matthew", middleName: "Matt", lastName: "Stevenson"))
    // Matthew Matt Stevenson
print(returnFullName("Matthew", middleName: nil, lastName: "Stevenson"))
    // Matthew Stevenson

现在,问题涉及解开给定示例的可选变量,上面已经很好地介绍了这一点。不过,我想我会提到,您可以使用闭包和 Swifts 内置函数方法来压缩您的解决方案,如下所示:

// instead of a function: make use of a closure
let returnFullName : (String, String?, String) -> String = {
    [$0, $1, $2].flatMap{ $0 }.joinWithSeparator(" ") }

print(returnFullName("Matthew", "Matt", "Stevenson"))
    // Matthew Matt Stevenson
print(returnFullName("Matthew", nil, "Stevenson"))
    // Matthew Stevenson

【讨论】:

  • 如果中间名为零,您的方法会在全名中留下两个空格。 "\(name.firstName) \(name.middleName + " " ?? "")\(name.lastName)" 应该可以解决问题。
  • @TomaszBąk 我正要解决这个问题。请注意,由于middleName 是可选的,因此您不能在之前向其添加空格" "(因此您上面的建议将产生编译时错误)。我建议改用 if let 语句。
  • 很棒的解释!现在看起来很明显。谢谢大家!
  • @GeoffreySetiawan 很高兴为您提供帮助。
【解决方案2】:

您应该只传递 firstName、middleName 和 lastName 的参数,而不是使用元组。在这种特殊情况下,元组似乎是不必要的。

    func returnFullName(firstName: String, middleName: String?, lastName: String) -> String?
    {
        if let middleName = middleName {
            return ("\(firstName) \(middleName) \(lastName)")
        } else {
            return ("\(firstName) \(lastName)")
        }
    }

let fullName = returnFullName("Matthew", middleName: "Matt", lastName: "Stevenson")

if let printFullName = fullName {
    print(printFullName)
}

【讨论】:

  • 如果middleName"Matt",这将打印"Matthew Optional("Matt") Stevenson",如果是nil"Matthew nil Stevenson".
  • 啊,我的错误,现在检查答案
  • 您能解释一下您的答案如何解决问题中的问题吗?仅代码的答案不是很有用,尤其是对于偶然发现这篇文章的更多读者。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-17
  • 2017-08-01
  • 1970-01-01
  • 2018-02-11
  • 2014-10-27
相关资源
最近更新 更多