xcode 如何在 Swift 中对结构进行子类化?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33914900/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 08:15:09  来源:igfitidea点击:

How do I subclass a struct in Swift?

iosxcodeswift

提问by Oleksandr

struct MyRect : CGRect {...}

Is it possible at all in swift to subclass a Structure?

是否有可能迅速对结构进行子类化?

I have already found out on Apple official website an example: This example extends the CGRect structure to contain a computed area property:

我已经在苹果官网上找到了一个例子:这个例子扩展了 CGRect 结构以包含一个计算区域属性:

extension CGRect {
    var area: CGFloat {
        return width * height
    }
}
let rect = CGRect(x: 0.0, y: 0.0, width: 10.0, height: 50.0)
let area = rect.area

How can i define a subclass of a structure ?

如何定义结构的子类?

回答by Sam Clewlow

It is not possible to subclass a structin Swift, only classes can be subclassed. An extensionis not a subclass, it's just adding additional functionality on to the existing struct, this is comparable to a category in Objective-C.

struct在 Swift 中无法对 a 进行子类化,只能对类进行子类化。Anextension不是子类,它只是在现有的 上添加附加功能struct,这与 Objective-C 中的类别相当。

Please see the Apple Swift documentation hereto read about the differences between structand class.

请参阅这里的苹果斯威夫特文档阅读有关之间的差异structclass

回答by James Hays

This is a bit old, but I ran across it and thought I'd post a common pattern I use when needed. For example, an Application I was working on had the need to do some work with AspectRatios. Well, in my mind, an AspectRatio is nothing for than a CGSize with some additional functionality. I wanted a little separation between an AspectRatio and a CGSize, so I created a TypeAlias and then created an extension of the TypeAlias.

这有点旧,但我遇到了它,并认为我会发布一个在需要时使用的通用模式。例如,我正在处理的一个应用程序需要使用 AspectRatios 做一些工作。好吧,在我看来,AspectRatio 只不过是具有一些附加功能的 CGSize。我想在 AspectRatio 和 CGSize 之间做一点分离,所以我创建了一个 TypeAlias,然后创建了一个 TypeAlias 的扩展。

Something like this:

像这样的东西:

public typealias AspectRatio = CGSize

public extension AspectRatio {
enum Orientation {
    case landscape
    case portrait
    case square
}
static let square = AspectRatio(width: 1.0, height: 1.0)
static let standard = AspectRatio(width: 4.0, height: 3.0)
static let wideScreen = AspectRatio(width: 16.0, height: 9.0)
static let theater = AspectRatio(width: 21.0, height: 9.0)
static let imax = AspectRatio(width: 1.9, height: 1.0)

func aspectRatio(precision: Int? = nil) -> CGFloat {
    let aspectRatio = width / height

    guard let precision = precision else {
        return aspectRatio
    }

    let multiplier = pow(10, Double(precision))

    let value = (Double(aspectRatio) * multiplier).rounded() / multiplier
    return CGFloat(value)
}

var orientation: Orientation {
    switch self.aspectRatio() {
    case let aspect where aspect > 1.0:
        return .landscape
    case let aspect where aspect < 1.0:
        return .portrait
    default:
        return .square
    }
}

func flipped() -> AspectRatio {
    return AspectRatio(width: height, height: width)
}    
...
}

Then I could easily define variables like such:

然后我可以轻松地定义这样的变量:

var aspectRatio: AspectRatio = .imax

回答by acecilia

Since Swift 5.1 it is now possible to do something similar to what you asked for: using composition, with KeyPathand dynamicMemberLookup. Have a look: https://medium.com/@acecilia/struct-composition-using-keypath-and-dynamicmemberlookup-kind-of-struct-subclassing-but-better-6ce561768612?source=friends_link&sk=da479578032c0b46c1c69111dfb6054e

从 Swift 5.1 开始,现在可以执行类似于您要求的操作:使用组合、使用KeyPathdynamicMemberLookup。看看:https: //medium.com/@acecilia/struct-composition-using-keypath-and-dynamicmemberlookup-kind-of-struct-subclassing-but-better-6ce561768612?source=friends_link&sk=da479578032c0b46c1c69114edfb605