Private setter for var in primary constructor

Did not think about that. In that case I agree that the extra keyword should be both in the constructor and on the property

And in android @Parcelize

All parameters of the primary constructor must be properties ( val / var ), otherwise they can not be (de)serialized

  • If there is a non-property parameter, it is a compile-time error

What would you think about the following one?

owned field: Type

My idea is basically about the keyword owned, which would mean that, since the field is owned by the class, only that’s got the right to change its value.
Anyway, if owned can’t be stood with, you could think about any other keyword that makes sense.

3 Likes

What would be the purpose of this feature? How is it different from using a var with private setter?

var field: Type
    private set

I was referring to a private-set field in the primary constructor of a class. Not member fields within the block of the class

What about:

data class Example(val x: Type1, var y: Type2; private set, var z: Type3)

to indicate that y is a variable with private setter?
(even the syntax highlighter like it :slight_smile: )

2 Likes

Coming across this cause running into a similar issue, I think the best solution would be to create an annotation that could represent the access level. then your could specify custom access levels using the already existing mechanism for specifying annotations on properties, which already work in constructors.

so you could have

data class myDataClass(@set:Private var someVar)

There is no new syntax required, just annotation handling by the compiler.

The ugliness arises from that syntax is unique and does not appear anywhere else

Wouldn’t it be much more “Kotlin like” if inside the get/set we would use “it” instead of “field”?

2 Likes

I overcome my resentment long ago. If feels quite natural now. It probably could be handled better, but after some time it is quite OK.

2 Likes

I liked the idea of ​​@davidecannizzo, simple and clear

owned field: Type
3 Likes

Agreed, the property system has a poor return on complexity budget. Worst part of Kotlin, right after coroutines.

Being able to specify a private (or protected) set on a primary constructor parameter is still a feature I would like to see in Kotlin.

The data class example that @Christian.Bongiorno gave is a good example - and indeed, you could make it private and then define a second, public field to get its value.
However, it seems to me that the whole point of Kotlin’s get and set is to move away from the amount of unnecessary repetition / lines of code that the Java-style private member with public getter created.
The following (or other suggestions) may not be syntactically the prettiest:

data class Foo(private(set) var id: Long)

but, in my opinion, the alternative:

data class Foo(private var _id: Long) {
    val id get() = _id
}

is also not pretty syntax.

This behaviour is also relevant to Kotlin’s @Parcelize annotation, which can only apply to classes with primary constructors whose arguments are either var or val.
For a library I am working on, we have to decide between having these properties as public var even though we don’t really want them to be modifiable from outside the class body, or to have them as protected var but then write an extra property for each in order to publicly expose its value, creating extra lines of code that essentially duplicate what we’ve already defined

Any update is going on with this feature? Private setter should be natively supported as it is the first step to keep encapsulation in any class.

2 Likes

I suggest taking a more general approach. You can allow to redefine getter or setter for properties using the overload keyword:

val prop: String

overload var prop: String private set
1 Like