Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 在哪些条件下,我更喜欢计算属性而不是存储属性?_Swift - Fatal编程技术网

Swift 在哪些条件下,我更喜欢计算属性而不是存储属性?

Swift 在哪些条件下,我更喜欢计算属性而不是存储属性?,swift,Swift,我今天看到这段代码,想知道为什么不使用简单的静态存储属性 这是我很好奇的代码: class ApiKeys { // movie keys class var HomePage: String { get { return "homepage" } } class var Id: String { get { return "id" } } class var Overview: String { get { return "overview" } } class var PosterPath

我今天看到这段代码,想知道为什么不使用简单的静态存储属性

这是我很好奇的代码:

class ApiKeys {

// movie keys
class var HomePage: String { get { return "homepage" } }
class var Id: String { get { return "id" } }
class var Overview: String { get { return "overview" } }
class var PosterPath: String { get { return "poster_path" } }
class var ReleaseDate: String { get { return "release_date" } }
class var Runtime: String { get { return "runtime" } }
class var Tagline: String { get { return "tagline" } }
class var Title: String { get { return "title" } }
class var Rating: String { get { return "vote_average" } }


// query params
class var ApiKey: String { get { return "api_key" } }
class var Query: String { get { return "query" } }
}
这就是我编写相同代码的方式:

class ApiKeys {

static let homePage = "homepage"
static let id = "id"
static let overview = "overview"
static let posterPath = "poster_path"
static let releaseDate = "release_date"
static let runtime = "runtime"
static let tagline = "tagline"
static let title = "title"
static let rating = "vote_average"


//Query Params
static let ApiKey = "api_key"
static let query = "query" 
}

永远不需要重写变量,所以使用static应该是可以的。我错过什么了吗?使用第一种方法比使用第二种方法有什么好处或理由吗?

类变量可以被子类重写,而静态常量不能。这是我能想到的第一个区别。

如果需要,可以使用计算属性在运行时动态更改属性的值,就像Objective-C中的getter一样,您不能使用
static let
常量来实现这一点。

可能有点离题:但一种可能是人为的使用场景,其中无法使用静态存储属性,即如果您在对某些“常量”协议。可以允许符合此类协议的类/结构/etc访问受类型约束的泛型,其中这些泛型是唯一可以访问协议常量(限制对常量的访问)的上下文,而协议常量保证为常量(因为它们也可以直接从符合该协议的具体类型中使用,但这些类型可以用新值“覆盖”“常量”)

协议HasAccessToConstants{
/*因为我们没有设计“答案”,默认
下面的实现将始终用于对象
用于一般用途时符合本协议
上下文(即使他们试图“覆盖”这些
“常量”及其自己的实现,这些
只能针对具体类型访问自定义类型)*/
}
扩展HasAccessToConstants{
静态变量回答:Int{return 42}
/*对于协议:我们可以实现默认值
仅用于计算属性的实现*/
}
类Foo:HasAccessToConstants{
/*即使开发人员实现了自己的“常量”
实现时,这将不用于访问
通用上下文中的Foo类型*/
静态变量回答:Int{return 9}
}
仅用于对象访问Constants(对象:T)的函数{
//用obj做点什么。。。
//利用obj类型可用的常数
打印(“此对象类型可用的常量(例如\(T.theAnswer)”)
}
仅适用于访问constants(Foo())的对象
/*此对象类型可用的常量(例如“42”)*/
//不是真正的“常量”,因为它们可以被具体类型“重写”
print(Foo.theAnswer)//9(自具体类型)

再次强调,这是人为的,并包含在技术讨论中,因为我真的看不出在什么情况下这比其他更好的替代方案更有用。

就其价值而言,我根本不倾向于使用计算或存储的属性。与其将其定义为
类,不如将其作为
enum

enum ApiKey: String {
    // movie keys
    case HomePage    = "homepage"
    case Id          = "id"
    case Overview    = "overview"
    case PosterPath  = "poster_path"
    case ReleaseDate = "release_date"
    case Runtime     = "runtime"
    case Tagline     = "tagline"
    case Title       = "title"
    case Rating      = "vote_average"

    // query params
    case ApiKey      = "api_key"
    case Query       = "query"
}
这更准确地抓住了“键”可以是这些值之一的概念

你会这样使用它:

if key == ApiKey.HomePage.rawValue {
    ...
}



在回答您最初的问题“我应该在什么时候选择计算属性”时,答案是您通常使用它们来检索从其他属性计算的值,如果您想设置其他属性(可能是私有的),还可以选择使用它们属性和值。如果只是返回一些静态的、不变的字符串,那么使用计算属性没有什么好处。

您应该知道的一件事是,在古代的Swift中,静态属性不适用于类。您发现的代码可能从那个时代起就一直在维护。有趣的是,我不知道不过,我碰巧知道代码是最近写的,但这很好,谢谢你的输入。
if key == ApiKey.HomePage.rawValue {
    ...
}
if ApiKey(rawValue: key) == .HomePage {
    ...
}