13

好的,这里有一个关于 S/O 的问题,标题如下:

Swift:以字符串形式获取变量实际名称

从它的名字来看,这似乎正是我想要的。但是,查看已接受的答案(以及其他未接受的答案),他们指的是关键路径操作,这不是我所追求的。(即这不是重复的!)

就我而言,我希望将一个变量的名称存储在字符串类型的第二个变量中。

在 C# 中,这很简单nameof,就像这样......

int someVar = 3

string varName = nameof(someVar)
// 'varName' now holds the string value "someVar"

注意:nameof()在编译时执行,而不是在运行时执行,因此不需要反射或其他任何东西。编译器只是简单地替换变量的名称,就好像有人手动将其名称键入为字符串常量一样。

例如,当您想要定义一个查询对象时,您的成员名称与 URL 中传递的查询参数相匹配,这非常方便。

这是一个伪代码示例(即,这显然不会编译,但显示了我所追求的。)

另外,请不要专注于 URL 方面。这绝对是*糟糕的代码*。在实际代码中,我会使用URLComponents,而不是像我在这里做的那样对 URL 进行字符串附加。同样,这*仅*说明了我的问题,而不是构建 URL。

struct queryObject{

    let userName  : String
    let highScore : Int

    var getUrl:String{
        return "www.ScoreTracker.com/postScore?\(nameof(userName))=\(userName)&\(nameof(highScore))=\(highScore)"
    }
}

以下是你如何使用它以及它会返回什么:

let queryObject = QueryObject(userName:"Maverick", highScore:123456)

let urlString = queryObject.getUrl

返回值将是:

www.ScoreTracker.com/postScore?userName=Maverick&highScore=123456

访问变量的字符串表示而不是使用字符串常量的优点有很多:

  1. 没有硬编码的字符串。
  2. 您可以像往常一样使用符号的重构/重命名和生成的字符串跟踪
  3. 允许您使 API 和实现保持同步,这有助于提高可读性。

例如,假设 API 将查询参数从 更改userNameuserId,只需重构变量名称,输出就会相应更新,而无需手动触摸任何字符串。

那么,这可以在 Swift 中完成吗?你能得到实际的变量名并将其存储在第二个变量中吗?

4

2 回答 2

1

是的你可以。我将其用作下一个场景的解决方案:当我在控制台中打印一个对象/结构时,我喜欢查看变量名称以及相关值:

extension CustomStringConvertible {
    var description: String {
        var description = "\n          *****  \(type(of: self)) *****\n"
        let mirrorS = Mirror(reflecting: self)
        for child in mirrorS.children {
            if let propertyName = child.label {
                description += "   \(getSpaces(forWord: propertyName))\(propertyName):  \(child.value)\n"
            }
        }

        return description
    }
}

为了使用它,让我们以以下结构为例:

public struct FavoriteApp: Codable, CustomStringConvertible, Hashable {
    let appId: String
    let appName: String
    let bundleId: String
    let image: NSImage
    let isMacApp: Bool
    let rating: String
    let screenshotUrls: [String]
    let sellerName: String
    let sellerUrl: String
    let releaseDate: String
    let genres: String
    let latestVersion: String

}

let anApp:FavoriteApp = getTheAppInfoFromServer()
print(anApp) 

// This will print into console: 
    //        *****  FavoriteApp *****
    //        appId:          1438547269
    //        appName:        Dynamic wallpaper
    //        bundleId:        com.minglebit.DynamicWallpaper
    //        image:           -not visible- (but is there, trust me :))
    //        isMacApp         true
    //        rating:          0
    //
    //        screenshotUrls:  https://is1-ssl.mzstatic.com/image/thumb/Purple128/v4/5c/08/b8/5c08b824-12eb-e0b6-22fb-0e234f396b9e/pr_source.jpg/800x500bb.jpg
    //                        https://is1-ssl.mzstatic.com/image/thumb/Purple128/v4/f3/34/0e/f3340e21-714c-0a17-4437-73ba1828cbba/pr_source.jpg/800x500bb.jpg
    //        sellerName:      MingleBit SRL
    //        sellerUrl:       https://minglebit.com/products/dynamicwallpaper.php
    //        releaseDate:     2018-10-18T14:59:47Z
    //        genres:          Entertainment, Lifestyle
    //        latestVersion:   2.3

所以,要集中答案,用Mirror(reflecting: object)得到你想要的。

于 2021-03-30T18:05:17.333 回答
1

如果只处理 URL,建议使用 URLComponents,这样比较好。

型号:</p>

struct QueryObject{

    var params = [String: String]()

    var getUrl: String{
        let result = "www.ScoreTracker.com/postScore"
        guard var url = URL(string: result) else { return result}
        url.appendQueryParameters(params)
        return url.absoluteString
    }

    init(params: [String: String]) {
        self.params = params
    }

}

然后:

    let params = ["userName": "Maverick", "highScore": "123456"]
    let queryObject = QueryObject(params: params)
    let urlString = queryObject.getUrl
    DDLog(urlString) //www.ScoreTracker.com/postScore?userName=Maverick&highScore=123456

Github链接

于 2021-06-28T03:26:05.113 回答