【问题标题】:swift: can a class or a struct have a kind of "main" property which can accessed without dot notation?swift:一个类或结构可以有一种“主要”属性,可以在没有点符号的情况下访问吗?
【发布时间】:2019-02-01 17:13:44
【问题描述】:

我正在使用静态结构来命名我的应用程序的常量。实际上,它们不是常量而是变量,所以以后用户可以更改其中的一些。

其中很多是依赖于字体大小的指标,因此嵌套在结构中的是另一个结构,它保存相对于字体大小的所需大小,但每当应用程序访问其中一个常量时,最终值计算出来的。

这是一个小代码示例:

public struct ApplicationConstants {

    public static var fontSize: Double = 24

    public struct RelativeSize {
        public var size: Double

        public init(_ size: Double) {
            self.size = size
        }

        public var double: Double {
            return size * fontSize
        }
    }
    public static var offsetAfterBulletPoint: RelativeSize = RelativeSize(0.3)
}

print(ApplicationConstants.offsetAfterBulletPoint.double) // returns 7.2
ApplicationConstants.fontSize = 16
print(ApplicationConstants.offsetAfterBulletPoint.double) // returns 4.8

为了更好的可读性,我更喜欢直接访问结果值而无需显式调用 .double 计算属性,如下所示:

print(ApplicationConstants.offsetAfterBulletPoint)

因为这个值是应用程序本身需要的唯一值。存储的相对于字体大小的值仅用于显示在可能的首选项窗格中,其中与字体大小的关系比结果值更容易理解。

我可以将值直接存储为双精度值并在初始化时进行计算:

public static var offsetAfterBulletPoint: Double = fontSize*0.3

但是我必须在 fontSize var 中实现一个 willSet 观察器,以便在字体大小发生变化时重新计算每个单独的字体相关值。在我的应用中,可能会有 100 多个这样的字体相关值。

那么,是否有协议或其他东西,它可以使我嵌套的 RelativeSize 结构的 .double var 成为一种“第一响应属性”,在调用变量而不指定成员时将返回该属性,以便它的行为如果它是原始的?

【问题讨论】:

  • 我建议不要在这种情况下使用静力学。我保证你会遇到这样一种情况,你要两个想要两个 ApplicationConstants,具有不同的值。
  • 你需要内部结构吗?您可以将所有这些变量都设置为静态变量。

标签: swift properties


【解决方案1】:

在你的情况下我会这样做:

public struct ApplicationConstants {

    public static var fontSize: Double = 24

    public struct RelativeSize {
        public var size: Double

        public init(_ size: Double) {
            self.size = size
        }

        public var double: Double {
            return size * fontSize
        }
    }
    private static var _offsetAfterBulletPoint: RelativeSize = RelativeSize (0.3)

    public static var offsetAfterBulletPoint : Double {
        get {
            return _offsetAfterBulletPoint.double
        } set {
            _offsetAfterBulletPoint = RelativeSize(newValue)
        }
    }
}

然后当你得到你将得到计算值。如果你设置了,你可以设置相对大小初始化器:

print(ApplicationConstants.offsetAfterBulletPoint) // prints 7.2
ApplicationConstants.offsetAfterBulletPoint = 0.4
print(ApplicationConstants.offsetAfterBulletPoint) // prints 9.6

如果您不喜欢使用相同的属性来设置和获取您的值,您也可以对变量进行一些操作

【讨论】:

  • 好的,使用 _ivars 实际上会让我得到想要的行为。不过,我希望可能有一种不那么冗长的方式......
【解决方案2】:

希望这会有所帮助!

方法一:使用计算属性

public struct ApplicationConstants {
    public static var fontSize: Double = 24
    public static var offsetAfterBulletPoint: Double {
        return fontSize * 0.3
    }
}

print(ApplicationConstants.offsetAfterBulletPoint) // returns 7.2
ApplicationConstants.fontSize = 16
print(ApplicationConstants.offsetAfterBulletPoint) // returns 4.8

方法二:使用静态函数

如果您希望用户知道调整大小的因素。

public static func offsetAfterBulletPoint(with factor: Double) -> Double {
    return fontSize * factor
}

方法3:使用闭包

public static let offsetAfterBulletPoint: ((Double) -> Double) = { factor in
    return fontSize * factor
}
print(ApplicationConstants.offsetAfterBulletPoint(0.3)) // returns 7.2
ApplicationConstants.fontSize = 16
print(ApplicationConstants.offsetAfterBulletPoint(0.3)) // returns 4.8

【讨论】:

  • 谢谢,但很遗憾,没有。我必须能够向用户公开 0.3 值,以便可以更改该值。在您的解决方案中,它将被硬编码。
  • @MassMover 因此,将0.3 因子提取到另一个变量中,但继续使用此处所示的计算属性。
  • @MassMover:感谢您阐明原因。我添加了一些其他方法。
猜你喜欢
  • 1970-01-01
  • 2019-04-05
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
相关资源
最近更新 更多