Why Choose Struct Over Class?

前端 未结 16 2301

Playing around with Swift, coming from a Java background, why would you want to choose a Struct instead of a Class? Seems like they are the same thing, with a Struct offeri

16条回答
  •  天涯浪人
    2020-11-22 06:12

    I wouldn't say that structs offer less functionality.

    Sure, self is immutable except in a mutating function, but that's about it.

    Inheritance works fine as long as you stick to the good old idea that every class should be either abstract or final.

    Implement abstract classes as protocols and final classes as structs.

    The nice thing about structs is that you can make your fields mutable without creating shared mutable state because copy on write takes care of that :)

    That's why the properties / fields in the following example are all mutable, which I would not do in Java or C# or swift classes.

    Example inheritance structure with a bit of dirty and straightforward usage at the bottom in the function named "example":

    protocol EventVisitor
    {
        func visit(event: TimeEvent)
        func visit(event: StatusEvent)
    }
    
    protocol Event
    {
        var ts: Int64 { get set }
    
        func accept(visitor: EventVisitor)
    }
    
    struct TimeEvent : Event
    {
        var ts: Int64
        var time: Int64
    
        func accept(visitor: EventVisitor)
        {
            visitor.visit(self)
        }
    }
    
    protocol StatusEventVisitor
    {
        func visit(event: StatusLostStatusEvent)
        func visit(event: StatusChangedStatusEvent)
    }
    
    protocol StatusEvent : Event
    {
        var deviceId: Int64 { get set }
    
        func accept(visitor: StatusEventVisitor)
    }
    
    struct StatusLostStatusEvent : StatusEvent
    {
        var ts: Int64
        var deviceId: Int64
        var reason: String
    
        func accept(visitor: EventVisitor)
        {
            visitor.visit(self)
        }
    
        func accept(visitor: StatusEventVisitor)
        {
            visitor.visit(self)
        }
    }
    
    struct StatusChangedStatusEvent : StatusEvent
    {
        var ts: Int64
        var deviceId: Int64
        var newStatus: UInt32
        var oldStatus: UInt32
    
        func accept(visitor: EventVisitor)
        {
            visitor.visit(self)
        }
    
        func accept(visitor: StatusEventVisitor)
        {
            visitor.visit(self)
        }
    }
    
    func readEvent(fd: Int) -> Event
    {
        return TimeEvent(ts: 123, time: 56789)
    }
    
    func example()
    {
        class Visitor : EventVisitor
        {
            var status: UInt32 = 3;
    
            func visit(event: TimeEvent)
            {
                print("A time event: \(event)")
            }
    
            func visit(event: StatusEvent)
            {
                print("A status event: \(event)")
    
                if let change = event as? StatusChangedStatusEvent
                {
                    status = change.newStatus
                }
            }
        }
    
        let visitor = Visitor()
    
        readEvent(1).accept(visitor)
    
        print("status: \(visitor.status)")
    }
    

提交回复
热议问题