我的代码中显然有一个可选项,但编译器认为我没有

时间:2017-04-21 15:10:11

标签: ios swift optional

我有这个功能:

func getTodaysDate() -> (day: String, date: String) {

    let currentDate = Date()
    let monthFormatter = DateFormatter()
    let dayFormatter = DateFormatter()

    monthFormatter.dateFormat = "MMMM"
    monthFormatter.locale = Locale(identifier: "en_US")
    let month = monthFormatter.string(from: currentDate)

    dayFormatter.dateFormat = "EEEE"
    dayFormatter.locale = Locale(identifier: "en_US")
    let dayToday = dayFormatter.string(from: currentDate)

    let calendar = Calendar.current
    let dateComponents = (calendar as NSCalendar).components([NSCalendar.Unit.day], from: currentDate)
    let day = String(describing: dateComponents.day)

    let date = ("\(month) \(day!)")

    return (day: dayToday.uppercased(), date: date.uppercased())

}

应返回:

  

星期五,4月21日

但它会返回:

  

星期五,四月可选(21)

我不能得到,因为这个不变的一天'不是可选的。即使我尝试解包它,编译器也会抱怨它

  

无法强制解包非可选类型'字符串'

的值

有谁知道发生了什么事?

1 个答案:

答案 0 :(得分:4)

在Swift 3中(与Swift 2不同)所有日期组件都是可选的:

var day: Int? { get set }

发生错误是因为您从可选的Int创建了一个字符串。结果是一个非可选字符串,但它包含文字" Optional()"

let day = String(describing: dateComponents.day) // --> "Optional(21)"

除了使用String Interpolation从字符串中冗余创建字符串之外,编译器会抱怨,因为字符串不是可选的。文字"可选()"是无关紧要的。

let date = ("\(month) \(day!)")

正确的语法是

let day = dateComponents.day!
let date = ("\(month) \(day)")

我建议使用原生的Swift 3语法(没有桥接到NSCalendar

let calendar = Calendar.current
let dateComponents = calendar.dateComponents([.day], from: currentDate)
let day = dateComponents.day! // needs to be unwrapped.

let date = ("\(month) \(day)")

由于您只需要一个组件,因此语法更简单(非可选)

let calendar = Calendar.current
let day = calendar.component(.day, from: currentDate)

let date = ("\(month) \(day)")