J A S K I E R
J A S K I E R

Reputation: 2184

How do I subclass a struct in Swift?

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:

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 ?

Upvotes: 22

Views: 36093

Answers (4)

slushy
slushy

Reputation: 12385

You cannot subclass structures in Swift but you can, in some sense, mimic subclassing by creating a structure that simply vends out the structure that you wish to subclass. For example, if you wanted to subclass Calendar (a structure), you could create a structure that returns configured calendars.

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 getAmerican() -> 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.getAmerican()

How you vend the configured structures (as an instance property, a static property, a static function, etc.) is just a matter of what better fits into your application and, frankly, personal preference.

Upvotes: 9

Sam Clewlow
Sam Clewlow

Reputation: 4351

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

Please see the Apple Swift documentation here to read about the differences between struct and class.

Upvotes: 37

James Hays
James Hays

Reputation: 71

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 more 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.

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

Upvotes: 2

acecilia
acecilia

Reputation: 938

Since Swift 5.1 it is now possible to do something similar to what you asked for: using composition, with KeyPath and 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

Upvotes: 2

Related Questions