有没有使用Swift的无大小写枚举而不是真实情况的技术原因?
有没有使用Swift的无大小写枚举而不是真实情况的技术原因?
作为对Swift不熟悉的人,我发现以下内容:
enum HttpMethod {
static let post = "POST"
static let get = "GET"
}
// 可以赋值给字符串属性。
request.httpMethod = HttpMethod.post // --> "POST"
在阅读了这个之后,使用无大小写的enum
而不是struct
的原因对我来说是有道理的,但这不是我感兴趣的事情。
基于我对C#的背景,这是我会如何实现它:
enum HttpMethod: String {
case post = "POST"
case get = "GET"
}
// 我甚至考虑以下这种方式:
enum HttpMethod: String {
case post
case get
}
// 必须获取字符串值
request.httpMethod = HttpMethod.post.rawValue // --> "POST"或者"post"
第二个版本需要使用rawValue
,但它将枚举视为真正的枚举。从C#中来,我习惯于在枚举值上使用.ToString()
。
这是否仅仅是个人偏好和Swift的惯例,即使用无大小写的枚举而不是实际的枚举值+rawValue,还是有其他(技术)原因使第一种版本优于第二种版本?
在Swift中,使用无案例的枚举(enum)有时比使用有案例的枚举更合适。无案例的枚举提供了一种存储常量的方式,这在决定如何存储常量时可能会变得棘手。无案例的枚举不可以实例化或构造,它只是一种列举静态常量属性的方式,可以像枚举一样访问。
以下是一个使用无案例枚举存储常量的示例:
enum Constants {
static let dateFormat: String = "dd.MM.yy"
static let timeFormat: String = "hh:mm:ss a"
static let defaultLocationCoordinates: CLLocationCoordinate2D = CLLocationCoordinate2DMake(-26.204103, 28.047305)
}
class Test {
static func echo() {
print("\(Constants.dateFormat)")
print("\(Constants.timeFormat)")
print("\(Constants.defaultLocationCoordinates)")
}
}
在上面的示例中,我们定义了一个无案例的枚举"Constants",其中包含了三个常量属性。我们可以通过枚举名字"Constants"来访问这些常量,就像访问枚举案例一样。
使用无案例枚举存储常量的好处是,它提供了一种结构化的方式来组织和访问常量。我们可以通过枚举名字来访问常量,而不需要创建一个实例。这使得代码更加清晰和可读,并且可以避免意外的实例化。
总结起来,使用无案例的枚举可以提供一种方便和结构化的方式来存储和访问常量。它可以避免意外的实例化,并且使代码更加清晰和可读。
如果你在Swift中需要存储常量,考虑使用无案例的枚举来实现。它是一种简洁和可靠的方法,可以提高代码的可维护性和可读性。
Swift的无案例枚举与实际案例的技术原因是什么?
在Swift中,使用无案例的枚举而不是实际案例有什么技术原因吗?这个问题的出现的原因是人们想知道在某些情况下,为什么使用无案例的枚举更好。同时,也提供了解决这个问题的方法。下面是对这个问题的原因和解决方法的整理。
枚举与案例
在以下情况下,最好创建一个具有案例的枚举:
- 它是互斥的
- 它是在编译时已知的有限值集
- 你是定义它的人(如果一个枚举在一个框架中被定义,你将无法扩展它以添加更多的案例)
枚举的优点:
- 由于值是有限的集合,你可以编写详尽的switch语句
- 代码更简洁
静态值:
当在一个框架中定义一个结构体/类,并且你想要扩展它以添加更多的值时,可以使用静态值。
一个使用这种方法的例子是Foundation框架中的Notification.Name。
注意:
- Swift中的枚举非常强大
- 枚举可以有关联值
- 枚举可以有其他函数(如果你正在定义像start、inProgress、finished这样的状态,你可以定义一个叫做next的函数,它可以返回下一个状态。start.next())
- 如果你的值不是互斥的,比如它可以是值的组合,那么使用OptionSet
结论
- 这完全取决于你的意图
- 如果你事先知道值,并且它们不会改变,那么创建一个枚举
- 如果不可能的话,那么创建静态值
- 如果你正在创建静态值,你是在妥协,所以你不必使用它在一个枚举中,你可以将其定义为一个结构体,以便意图更清晰
- 目前是这样,对于可扩展的枚举有一个Swift提案
问题的出现的原因:根据要解决的问题,是否使用带有字符串值的枚举取决于具体情况。如果需要一个无界的字符串集合,最好声明一个只有一个let rawValue: String
属性的结构体,并为已知的值声明静态实例。这就是苹果框架在诸如NSNotification.Name之类的情况下所做的。
解决方法:对于原始值声明为:String
的枚举,其自动实现了CustomStringConvertible(类似于.toString()),使用的是"\(enum-name)"
,而不是.rawValue,但它会打印出枚举的情况,而不是字符串。当需要打印原始值时,有时我会实现CustomStringConvertible来打印.rawValue。
"\(enum-name)"
返回的是枚举的情况名称,而不是关联的字符串。所以,原始问题的答主会得到"post"
而不是"POST"
。
对此我忘了,当我需要确切的字符串时,我通常声明CustomStringConvertible。我已经编辑了我的回答的这部分。