xcode 如何在Swift中子类化一个结构体?

uqjltbpv  于 2023-02-25  发布在  Swift
关注(0)|答案(4)|浏览(173)
struct MyRect : CGRect {...}

在swift中是否有可能对一个结构进行子类化?
我已经在苹果官网上找到了一个例子:此示例扩展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

如何定义一个结构的子类?

jum4pzuy

jum4pzuy1#

在Swift中struct不可能被子类化,只有类可以被子类化。extension不是子类,它只是在现有的struct上添加了额外的功能,这与Objective-C中的类别类似。
请参阅Apple Swift documentation here以了解structclass之间的差异。

vsdwdz23

vsdwdz232#

在Swift中,你不能对结构进行子类化,但在某种意义上,你可以通过创建一个结构来模拟子类化,该结构只提供你想要子类化的结构。例如,如果你想对Calendar(一个结构)进行子类化,你可以创建一个返回已配置日历的结构。

struct WorldCalendar {
    let american1: Calendar = {
        var c = Calendar(identifier: .gregorian)
        c.timeZone = .current
        c.locale = Locale(identifier: "en_US_POSIX")
        return c
    }()
    
    static let american2: Calendar = {
        var c = Calendar(identifier: .gregorian)
        c.timeZone = .current
        c.locale = Locale(identifier: "en_US_POSIX")
        return c
    }()
    
    static func american3() -> Calendar {
        var c = Calendar(identifier: .gregorian)
        c.timeZone = .current
        c.locale = Locale(identifier: "en_US_POSIX")
        return c
    }
}

let worldCalendar = WorldCalendar()
let cal1 = worldCalendar.american1

let cal2 = WorldCalendar.american2

let cal3 = WorldCalendar.american3()

如何销售配置的结构(作为示例属性、静态属性、静态函数等)只是一个问题,即什么更适合您的应用程序,坦率地说,这取决于个人喜好。

zbdgwd5y

zbdgwd5y4#

这是一个有点老的,但我偶然发现它,并认为我会张贴一个常用的模式,我用在需要的时候。例如,一个应用程序,我正在做的需要做一些工作与AspectRatio。嗯,在我看来,一个AspectRatio只不过是一个CGSize与一些额外的功能。我想一个小的分离之间的AspectRatio和CGSize。所以我创建了一个TypeAlias,然后创建了一个TypeAlias的扩展。
大概是这样的

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)
}    
...
}

然后我可以很容易地定义如下变量:

var aspectRatio: AspectRatio = .imax

相关问题