The only way I can think of is to have a private c...
# announcements
n
The only way I can think of is to have a private class Key at file scope, and then the class in question can members that accept a Key. Seems a bit hacky though.
s
If your extension function needs access to private or protected members, you have to make them members of that class. I don’t think there is a way around it….
n
an extension function that's a member of the class can only be used inside the class
so, that won't work for what I need
to be clear, it's an extension function for a different class, than the one it's related to/needs access to
s
Ah… sorry… yup, then making them member of that class won’t work. Alas, there is no such lexical scope as ‘file private’ or something similar or like ‘friend’ in C++.
n
yeah, friend would be nice. I would have thought that since Kotlin encourages free functions and extension functions related to classes, there would be a way to do this
s
Actually, you can do something like this:
Copy code
class SomeClass {
    private var counter: Int = 1
    
    fun OtherClass.updateCounter() {
        counter += this.otherCounter
    }
}

class OtherClass {
    val otherCounter: Int  = ...
}  

... 
with (someClass) {
    otherClass.updateCounter()
}
...
n
Basically I have this:
Copy code
class ImmutableList<T> internal constructor(val data: List<T>) : List<T> by data {
And I want to have extension functions like this:
Copy code
fun <T> Iterable<T>.toImmutableList() = ImmutableList<T>(this.toList())
arg
Without having to use
with
or anything like that
The problem in this example is that the constructor can't be publicly accessible, because then someone can easily construct a mutable list, pass it in, and then mutate it out from under me
I could have public constructors that accept only sequence/iterable, but then that's less efficient for certain extension functions
s
Yup, I see you problem. Sticking the code of your
ImmutableList
and the
toImmutableList
in a separate module will allow this (
internal
scope), but if the client of your code is in the same module, you’re out of luck….
n
yeah, and modules are big. I'm just thinking practically, if I'm working on a company codebase, I probably won't bother creating multiple modules within a single team
but that doesn't mean that everything can access that
here's my solution btw
s
Even a lexical scope of
package private
would work. There are a few issues/requests out there to add that scope for Kotlin (like in Java).
n
hmm maybe kotlin won't allow it. that's really annoying 🙂
Copy code
Error:(7, 11) Kotlin: 'public' function exposes its 'private' parameter type Key
how infuriating
🙂
m
As I’ve also written in YouTrack - you can use a
sealed class
for that 🙂
n
@Marc Knaup good point 🙂
Amusingly, it works because sealed class is the only thing in kotlin that is 'same file only'
This is kind of ironic given that the kotlin team has been really obstinate about adding such an access control level
m
I’m not sure what you mean. Everything at file-level that is declared
private
is “same file only”.
n
not class members
But I take your point
m
Yeah, something like
fileprivate
in Swift would be nice sometimes 🙂
n
Yeah, definitely for this use case. Or, to be honest, even friendship, or even the passkey idiom that I mentioned as point 3 in mypost
the thing is that it feels a tiny bit verbose but it's actually also very fine grained andclear
m
With the
sealed class
trick you could also make keys. But it’s a weird workaround imo 😅
n
yeah, i was thinkign that. it makes it even more verbose 🙂