Swift Protocol get only settable?

前端 未结 6 725
一生所求
一生所求 2020-12-08 00:23

why can I do this without any error:

var testDto = ModelDto(modelId: 1)
testDto.objectId = 2

while I define this:

protocol          


        
6条回答
  •  误落风尘
    2020-12-08 01:28

    I'm answering the question in it's generic sense.

    Before addressing the question you must know what does get & set mean.

    (If you'r coming from an Objective-C world:) get means readOnly, that is I'm allowed to know the number of legs an animal has. I'm not allowed to set it. get & set together means readWrite ie I'm allowed to know the weight of an animal while I'm also able to set/change the weight of an animal

    With the following example.

    protocol Animal {
        var weight : Int { get set }
        var limbs : Int { get }
    }
    

    If you only have getter, and attempt to hide setter (by using private (set)... then you WON'T get an error ... it's likely what you wanted and how it must be done!

    Likely what you intended:

    class Cat : Animal {
        private (set) var limbs: Int = 4 // This is what you intended, because you only have get requirements...and don't want any conforming type to be able to set it ie don't want others do catInstance.limbs = 22
        var weight: Int = 15
    
    }
    
    var smallCat = Cat()
    smallCat.weight = 20 // Good!
    
    // attempting to set it will create an error!!!
    smallCat.limbs = 5 // Error: Cannot assign to property: 'limbs' setter is inaccessible
    

    Likely what you didn't intend:

    class Panda : Animal {
        var limbs: Int = 4 // This is OK, but it kinda defeats the purpose of it being a get only
        var weight: Int = 200   
    }
    
    var littlPanda = Panda()
    
    littlPanda.weight = 40 // Good
    littlPanda.limbs = 30 // NO Error!!! Likely unintended
    

    Basically with {get} there is still some extra work to be done which the compiler doesn't tell you ... YOU must add private (set) to achieve the intended behavior


    If your property has setter and you attempt to hide setter then you will actually see an error.

    class Dog : Animal {
        private (set) var limbs: Int = 4
        private (set) var weight: Int = 50  // Error: Setter for property 'weight' must be declared internal because it matches a requirement in internal protocol 'Animal'
    }
    

    You're not allowed to hide, because you promised to provide a setter...

提交回复
热议问题