【问题标题】:Unable to access struct variable defined inside #if directive无法访问 #if 指令中定义的结构变量
【发布时间】:2018-05-29 10:12:43
【问题描述】:

我已经在我的项目中成功配置了 3 个不同的环境。我正在尝试根据方案中设置的配置访问基本 URL。

如何从下面的代码中访问名为“BASE_URL”的变量,例如

AppConstants.API.BASE_URL

class AppConstants
{
    struct API
    {
        #if ENV_DEV
        static let BASE_URL = "http://api_dev .../"
        #endif

        #if ENV_STAGE
        static let BASE_URL = "http://api_stag .../"
        #endif

        #if ENV_PROD
        static let BASE_URL = "https://api_prod .../"
        #endif
    }
}

我知道这可以做到,因为我可以在其他项目中以这种方式访问​​:

更新:

  • 来自其他项目:

更新 2:

我已将活动编译条件中的环境变量设置为:

我想我遗漏了一些东西,可能是在构建设置中。

【问题讨论】:

  • 为什么这需要是一个类?
  • 如何访问它,错误信息是什么?
  • 它甚至可以编译吗?从编译器的角度来看,您的 BASE_URL 声明并不相互排斥。没有任何东西(除了开发人员的注意)可以防止两个或所有三个 #if 检查通过并且 BASE_URL 被多次声明。
  • @iAkki:有一个错字:构建设置中的 ENV_STAG 和代码中的 ENV_STAGE。除此之外,它应该完全按照您的方式工作。
  • 投票结束作为离题(简单的印刷错误)。

标签: ios swift struct environment preprocessor-directive


【解决方案1】:

刚刚测试了以下代码,它应该可以工作。您基本上需要将其从所有#if 转换为使用#elseif#else。这是因为如果没有任何陈述为真,BASE_URL 可能不存在。

您还可以设置默认值并在每个if 语句中更改它。但是,如果if 语句都不为真,您需要以某种方式定义变量将是什么。

class AppConstants
{
    struct API
    {
        #if ENV_DEV
        static let BASE_URL = "http://api_dev .../"
        #elseif ENV_STAGE
        static let BASE_URL = "http://api_stag .../"
        #else
        static let BASE_URL = "https://api_prod .../"
        #endif
    }
}

print(AppConstants.API.BASE_URL)

请记住,如果 if 语句不正确,此解决方案将默认使用最后一个基本 url。在最初的问题中没有默认值。这种行为是否可以接受取决于您的配置。

【讨论】:

  • 谢谢。这很完美。但是为什么它不能通过 onlt #if 访问,就像更新问题中的屏幕截图中显示的那样?
  • 我不知道为什么你的第一个更新截图有效。我认为您应该安全并设置默认值。正如 user28434 所说,除了开发人员的注意之外,没有什么可以防止它被多次声明。这通常是一件坏事,并为问题打开了大门。防守代码。在此处使用带有默认值的 if else 语句并确保始终声明 BASE_URL 似乎是最好的方法。
  • 我不同意这个解决方案。如果每个配置都需要一个专用的基本 URL,那么构建设置中缺少的定义是一个 编程错误 并且不应该编译,而不是默默地退回到 some URL。 – 也没有解释为什么 OP 的代码不能编译。
  • @MartinR 如果您有更好的解决方案,请随时发布。尽管我同意您的说法,但如果不确保已声明该变量,我将无法访问该变量。不知道如何使用原始代码来做到这一点。但是,如果您有更好的解决方案,请随时回答。各有利弊。
  • @iAkki 这取决于你想要什么。如果您的代码中存在问题,例如您遇到的拼写错误。您是否希望它使用默认的基本网址(我上面的解决方案)?还是您希望它抛出错误(更正拼写错误后的代码)?无论哪种方式在技术上都有效。但这取决于您想要什么以及您希望如何处理那些程序员的错误和极端情况。
【解决方案2】:

为了保护自己不设置正确的编译标志,你可以使用类似的东西:

class AppConstants
{
    struct API
    {
        static let BASE_URL: URL = { () -> URL in // URL should be URL
            let baseURLString: String

            #if ENV_DEV
                baseURLString = "http://api_dev .../"
            #endif

            #if ENV_STAGE
                baseURLString = "http://api_stag .../"
            #endif

            #if ENV_PROD
                baseURLString = "https://api_prod .../"
            #endif

            return URL(string: baseURLString)! // If no proper flag is set, you will get error here
        }()
    }
}

这里,如果不设置任何标志,你会得到错误。

如果您像原始代码一样设置多个标志,它会不断引发错误。

【讨论】:

    猜你喜欢
    • 2017-10-15
    • 1970-01-01
    • 2014-03-21
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    相关资源
    最近更新 更多