Swift 3:如何呼叫;“自我”;作为财产?

Swift 3:如何呼叫;“自我”;作为财产?,swift,swift3,Swift,Swift3,我有一个关于Swift 3的问题。在Swift 3中,我知道我可以做到: struct Movie { let title = String let rottenTomatoesRating = Double } 但是,假设我创建了一个新实例: let StarWars = Movie(title: "Star Wars", rottenTomatoesRating: 97) 是否有任何方法可以使用变量名“星球大战”,即实例名,将其添加/用作title属性。我知道在一些编程语

我有一个关于Swift 3的问题。在Swift 3中,我知道我可以做到:

struct Movie {
    let title = String
    let rottenTomatoesRating = Double
}
但是,假设我创建了一个新实例:

let StarWars = Movie(title: "Star Wars", rottenTomatoesRating: 97)
是否有任何方法可以使用变量名“星球大战”,即实例名,将其添加/用作title属性。我知道在一些编程语言中,有一个“self”属性。在Swift 3中甚至可以这样做吗

另一个例子是:

struct Song {
    let genre: String
    let songTitle: String
    let artist: String
    let album: String
    var formattedSong: String {
        print("Now playing \(songTitle), \(-------SONG-------) by \(artist).")
    }
}
是否可以在变量“formattedSong”中引用实例名称,如下所示:

let myfavoriteSong = Song.formattedSong
let lastSongIListenedTo = Song.formattedSong
即使这不是最实际的例子,我想知道这是否可行。谢谢你的阅读

是否有任何方法可以使用变量名“星球大战”,即实例名,将其添加/用作title属性

不,好吧,是的,但要完全按照你的方式来做。变量名不是运行的编程可以神奇地看到并转换为字符串的东西

如果要使用字符串指定某事物的名称,请使用带有字符串键的词典:

var d = [String:Any]()
let title = "Star Wars"
d[title] = Movie(title: title, rottenTomatoesRating: 97)
是否有任何方法可以使用变量名“星球大战”,即实例名,将其添加/用作title属性

不,好吧,是的,但要完全按照你的方式来做。变量名不是运行的编程可以神奇地看到并转换为字符串的东西

如果要使用字符串指定某事物的名称,请使用带有字符串键的词典:

var d = [String:Any]()
let title = "Star Wars"
d[title] = Movie(title: title, rottenTomatoesRating: 97)
属性名是在编译时自然给出的(由开发人员),因此没有理由在编译时使用这些名称来设置属性本身的值;这些值可以直接输入

小心行事

对于技术讨论,您可以为此实现一个非Swift本机hack(但不应),将使用
Mirror
的运行时内省与子类化
NSObject
相结合,后者构建一个电影容器,可以使用
NSObject
的方法设置值

然而,这样做有点疯狂

另一方面,如果您只想检查属性(它们的名称和值),特别是出于调试目的,那么内省(上面的
Mirror
部分,而不是
NSObject
子类化)可能很有用。

属性名称自然会在编译时给出(由开发人员),所以并没有理由在编译时使用这些名称来设置属性本身的值;这些值可以直接输入

小心行事

对于技术讨论,您可以为此实现一个非Swift本机hack(但不应),将使用
Mirror
的运行时内省与子类化
NSObject
相结合,后者构建一个电影容器,可以使用
NSObject
的方法设置值

然而,这样做有点疯狂


另一方面,如果您只想检查属性(它们的名称和值),特别是出于调试目的,那么内省(上面的
Mirror
部分,而不是
NSObject
子类化)可能会很有用。

请澄清,您所要求的类似于
Movie.instances(标题为:“星球大战”)
,在您的示例中,哪个应该返回
电影
?这里的
变量名“星球大战”
在哪里?它似乎是一个可变值。你甚至不应该觉得有必要这样做。只是要明确一点,你要求的是类似于
电影的东西。实例(标题为:“星球大战”)
,在你的例子中,它应该返回
电影
?这里的
可变名称“星球大战”
在哪里?它看起来像一个变量值。你甚至不应该觉得有必要这么做。“变量名不是运行程序“@dfri”可以神奇地看到并转换成字符串的东西,但在OP的问题中,它只是一个局部变量,所以你的反对在这里是不相关的。它从来不是反对的意思,但只是一个署名(因此称为“除非…”),因为我们不知道《星球大战》的财产是在什么样的背景下存在的;OP没有明确地声明它是一个局部变量。因此,我不会真的认为署名无关紧要:)我想说的是,给出你的答案,好吧,@dfri,但不要用你的评论破坏我的答案,好像我的答案是错的。再说一次,我从来没有打算说你的答案是错的,我认为,从我的评论中可以清楚地看出,这只是添加了一个特例,我们实际上可以获得一个属性名,作为
字符串(对于这种情况,这是一个正确的语句),我相信这对于阅读此答案的OP/读者来说是有价值的。如果我的非母语英语真的很不清楚,并且被认为是来自你方的完全负面的批评,我将不得不大声抱怨。至于“破坏”你的答案:注释SO答案(试图)添加可能有价值的信息,imho,是注释SO的核心用途。“变量名不是运行编程时可以神奇地看到并转换为字符串的东西”@dfri,但在OP的问题中,它只是一个局部变量,所以你的反对在这里是无关紧要的。它从来都不是反对的意思,只是一个署名(因此称为“除非…”),因为我们不知道《星球大战》
的财产是在什么背景下存在的;OP没有明确地声明它是一个局部变量。因此,我不会真的认为署名无关紧要:)我想说的是,给出你的答案,好吧,@dfri,但不要用你的评论破坏我的答案,好像我的答案是错的。再说一次,我从来没有打算说你的答案是错的,我认为从我的评论中可以清楚地看到,它只是添加了一个特例,我们实际上可以将属性名作为
字符串
(一个stat)
import Foundation

class Movie: NSObject {
    var title: String
    var rottenTomatoesRating: Double
    init(title: String, rottenTomatoesRating: Double) {
        self.title = title
        self.rottenTomatoesRating = rottenTomatoesRating
    }
}

class MovieLibrary: NSObject {
    var starWars = Movie(title: "", rottenTomatoesRating: 4.6)
    var indianaJones = Movie(title: "", rottenTomatoesRating: 4.2)
    // ...

    func setTitlesToPropertyNames() {
        for case (let label as String, is Movie) in Mirror(reflecting: self).children {
            self.setValue(label, forKeyPath: label + ".title")
        }
    }
}

var library = MovieLibrary()
library.setTitlesToPropertyNames()
print(library.starWars.title)     // "starWars"
print(library.indianaJones.title) // "indianaJones"