Swift-如何初始化NSDate属性的默认值?

Swift-如何初始化NSDate属性的默认值?,swift,datetime,nsdate,default-value,Swift,Datetime,Nsdate,Default Value,我有一个简单的类定义: class Course{ var date:NSDate init(){ } } 例如,在c#中,创建此类时,date属性的默认值为DateTime.MinValue 我不想让这成为一次约会?因为根据我的商业逻辑 此属性是必须的,每门课程都有日期。(设置为NSDate?意味着课程可以没有日期存在) 我不想把它设为现在,因为这是误导。现在可能是 一个有效值,来自我的业务逻辑的其他部分 如何在swift中执行相同的操作?您可以创建对NSD

我有一个简单的类定义:

class Course{

    var date:NSDate

    init(){

    }
}
例如,在c#中,创建此类时,date属性的默认值为DateTime.MinValue

  • 我不想让这成为一次约会?因为根据我的商业逻辑 此属性是必须的,每门课程都有日期。(设置为NSDate?意味着课程可以没有日期存在)

  • 我不想把它设为现在,因为这是误导。现在可能是 一个有效值,来自我的业务逻辑的其他部分


如何在swift中执行相同的操作?

您可以创建对
NSDate
的扩展,如下所示:

extension NSDate
{
    class func minimumDate() -> NSDate
    {
        let calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)!
        return calendar.dateWithEra(1, year: 1, month: 1, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)!
    }
}
这将允许您使用类似的
1/1/0001 00:00:00
时间戳实例化新的
NSDate

let myDate = NSDate.minimumDate()
Swift还有一个空合并运算符(
??
),它允许您在初始值设定项中执行以下操作:

class Widget
{
    var dateCreated : NSDate

    init(dateCreated: NSDate?)
    {
        self.dateCreated = dateCreated ?? NSDate.minimumDate()
    }
}

如果所有课程都需要有效日期,为什么要创建没有实际日期的课程?去掉
init()
,创建一个指定的初始值设定项

class Course{
    let date: NSDate

    init(date: NSDate) {
        self.date = date
    }
}
如果你坚持要有这些奇怪的“非真实日期”,你可以使用
distantpass()


如果您总是在
init
方法中初始化
date
(如您所说,如果它必须有一个日期),则以下情况可以:

class Course {    
    var date: Date          // if Swift 2 we’d use `NSDate`, but in Swift 3 and later, we’d use `Date`

    init() {
        date = ... // set it to some reasonable, default value
    }
}
或者,如果没有合理的默认值,您可以指定一个初始值设定项,在其中提供值:

class Course {    
    var date: Date

    init(date: Date) {
        self.date = date
    }
}
但是,如果由于某些原因,无法在实例化对象时指定值,并且只能在稍后的某个点设置日期,但从该点开始,它应该始终具有一个值,则可以使用隐式展开的可选值。至于隐式展开的选项,则表示:

有时,从程序的结构中可以清楚地看出,在第一次设置该值之后,optional将始终具有一个值。在这些情况下,消除每次访问可选项时检查和打开可选项值的需要是很有用的,因为可以安全地假设它一直都有值

这些类型的选项被定义为隐式展开的选项。通过在要设置为可选的类型后放置感叹号(
String!
)而不是问号(
String?
),可以编写隐式展开的可选类型

因此,你应该

class Course {
    var date: Date!

    init() {
        // the `date` is not necessarily set here, but once it is set, it shouldn't be `nil` thereafter
    }
}

是的,从技术上讲,对于隐式展开可选,
date
可以是
nil
,但实践是,如果它最初可能是
nil
,但一旦设置,它将不再是
nil
,您将使用隐式包装可选。

这将起作用,但我认为这种情况下隐式展开的可选值(也称为“感叹号值”)并不合适。
init
应该设置它。我同意。OP的场景中弥漫着代码气味:(a)每个
课程都必须有日期;但也暗示(b)他想创建一个
课程
,但既不提供
日期
值,也没有任何有意义的默认值。尽管有时我们必须这样做(在这些情况下,隐式展开选项是正确的解决方案),但我同意,像这样的简单模型对象很少属于这一类。但是使用默认的哨兵值,如
distantpass
,只是为了避免使用选项,是一种根本上有缺陷的方法
class Course {
    var date: Date!

    init() {
        // the `date` is not necessarily set here, but once it is set, it shouldn't be `nil` thereafter
    }
}