Is there a way in kotlin to create a generic property without declaring a class level generic type? Something that looks like this:
interface Generic {
val t: T //I need this type only once, thats why I dont wanna pass in the class level
fun <E> gMethod(e: E) { //This works, so I'm wondering if there's something similiar to properties
}
}
Since the documentation about generics has no mention of such thing, I'm pretty sure this isn't a part of the language.
This is most likely because you have to declare the type of the property at some point. Generic functions make sense, because you call them with arguments that have some sort of a static type (or in the case of extension functions, call them on such arguments).
The question is, why would you want to have a generic property like this?
What would you expect this property to accept as a value when you're trying to set it? If the answer is anything, maybe its type should be Any or Any?.
The same applies for reading it - what type would you expect the value you're reading from this property to have? If you don't want to specify a type at all, again, it should probably be Any or Any?.
The solution that's actually in the language, that is having the class/interface take a type parameter, solves these issues.
I'm a complete newbie to Kotlin, but a generic property is not really something wrong, is it?
What about this as a showcase. I do understand that this solution does not completely address your question.
interface BaseProperty<T> {
var value: T
}
class IntProperty(var stringVal: String) : BaseProperty<Int?> {
override var value: Int?
get() = Integer.valueOf(stringVal)
set(v: Int?) {
stringVal = v.toString()
}
}
Since the getter and setter of the property are also a functions, it would had been nice if I were able to specify T as generic type. I have tried to use getValue and setValue as generic functions and that seems to work, but not using the Kotlin property idiom.
No, how should the compiler know what T is? If you don't need the generic type parameter T anyway, you can just declare it as val t: Any.
private val <T> List<T>.mutable: MutableList<T>
get() = this.toMutableList()
#Test
fun demonstrate_genericProperty() {
val numbers = listOf(1, 2, 3, 4)
val mutableNumbers = numbers.mutable
println("numbers = ${numbers}")
println("mutableNumbers = ${mutableNumbers}")
println("(numbers === mutableNumbers) = ${(numbers === mutableNumbers)}")
}
Related
I am still learning kotlin, and I am curious how is it possible that mockk is able to return some object T wrapped in Result<T>. For better understanding let analyse below example:
We have such method definition
fun save(toSave : Entity): Result<Entity>
when we mock such method using returnArguments like it is done below:
every { mocked.save(any()) } returnsArgument 0
Then method returns Result<Entity>, but logic says that Entity should be returned.
Looking into declaration of returnsArgument there is casting to generic type which in our case is Result<Entity>, but when I tried to do it in plain I had casting exception.
I assume some magic happens inside, but what magic is responsible for such thing?
Would it be done with any wrapping object or it is specific only to Result?
Result<T> is a value class and mockk has a value class support.
After many internal steps returnsArgument will wrap the argument n with the specified value class and will return it.
Would it be done with any wrapping object or it is specific only to Result?
All value classes are supported, not just Result<T>.
// supported
#JvmInline
value class ValueWrapper<out T> (val something: Any?)
// not supported
class SomeWrapper<out T> (val something: Any?)
Hope it helps.
I'm trying to access the delegate of the property (id) of a class (FooImpl). The problem is, this class implements an interface (Foo), and the property in question overrides a property of this interface. The delegate only exists in the class (not that it could exist in the interface).
The problem is that using the :: operator on a variable of type Foo always returns the property of Foo, not that of the actual instance. The problem in code:
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
import kotlin.reflect.jvm.isAccessible
interface Foo {
val id: Int
}
class FooImpl(
id: Int,
) : Foo {
override val id: Int by lazy { id }
}
val <T> KProperty<T>.hasDelegate: Boolean
get() = apply { isAccessible = true }.let { (it as KProperty0<T>).getDelegate() != null }
fun main() {
val foo: Foo = FooImpl(1)
println("foo::id.hasDelegate = ${foo::id.hasDelegate}")
println("(foo as FooImpl)::id.hasDelegate = ${(foo as FooImpl)::id.hasDelegate}")
}
This prints:
foo::id.hasDelegate = false
(foo as FooImpl)::id.hasDelegate = true
But this requires compile-time knowledge of the correct implementation. What I'm looking for is accessing the correct propert without having to specify FooImpl there.
The information is present at runtime because the least (!) intrusive workaround I have found so far is adding fun idProp(): KProperty0<*> to Foo and override fun idProp() = ::id to FooImpl and accessing the property using that.
Is there any better way than that?
I came up with this, but I don't know if there's a better way. The problem to work around is that getDelegate() has to return an actual instance of the delegate, so you need an instance of the class to be able to retrieve a delegate instance. It would really be nice if there was a hasDelegate property built in. Your version of hasDelegate will crash from the cast on unbound KProperty1's, which is all we have to work with when the specific class is unknown.
So to retrieve the delegate instance, we need to do search the class instance's member properties by name, which gives us a KProperty with covariant class type of the super-class type. Since it's covariant, we can call a consuming function like getDelegate() without casting to the invariant type. I think this logically should be safe, since we are passing an instance that we know has the matching type for the ::class that we retrieved the property with.
#Suppress("UNCHECKED_CAST")
fun <T: Any> KProperty1<T, *>.isDelegated(instance: T): Boolean =
(instance::class.memberProperties.first { it.name == name } as KProperty1<T, *>).run {
isAccessible = true
getDelegate(instance) != null
}
fun main() {
val foo: Foo = Foo2()
println("foo::id.hasDelegate = ${Foo::id.isDelegated(foo)}")
}
The problem here is that the owner of the property is resolved on compile time, not on runtime. When you do foo::id then foo (so FooImpl) become its bound receiver, but owner is still resolved to Foo. To fix this we wound need to "cast" property to another owner. Unfortunately, I didn't find a straightforward way to do this.
One solution I found is to use foo::class instead of foo::id as it resolves KClass on runtime, not on compile time. Then I came up with almost exactly the same code as #Tenfour04.
But if you don't mind using Kotlin internals that are public and not protected with any annotation, you can use much cleaner solution:
val KProperty0<*>.hasDelegate: Boolean
get() = apply { isAccessible = true }.getDelegate() != null
fun KProperty0<*>.castToRuntimeType(): KProperty0<*> {
require(this is PropertyReference0)
return PropertyReference0Impl(boundReceiver, boundReceiver::class.java, name, signature, 0)
}
fun main() {
val foo: Foo = FooImpl(1)
println(foo::id.castToRuntimeType().hasDelegate) // true
}
We basically create a new instance of KProperty, copying all its data, but changing the owner to the same type as its bound receiver. As a result, we "cast" it to the runtime type. This is much simpler and it is also cleaner because we separated property casting and checking for a delegate.
Unfortunately, I think Kotlin reflection API is still missing a lot of features. There should be hasDelegate() function, so we don't have to provide receivers, which is not really needed to check if property is delegated. It should be possible to cast KProperty to another type. It should be possible to create bound properties with some API call. But first of all, it should be possible to do something like: Foo::id(foo), so create KProperty of the runtime type of foo. And so on.
I'm exploring the Substitution principal and from what I've understood about the principal is that a sub type of any super type should be passable into a function/class. Using this idea in a new section of code that I'm writing, I wanted to implement a abstract interface for a Filter like so
interface Filter {
fun filter(): Boolean
}
I would then imagine that this creates the contract for all classes that inherit this interface that they must implement the function filter and return a boolean output. Now my interpretation of this is that the input doesn't need to be specified. I would like it that way as I want a filter interface that guarantee the implementation of a filter method with a guarantee of a return type boolean. Does this concept even exists in Kotlin? I would then expect to implement this interface like so
class LocationFilter {
companion object : Filter {
override fun filter(coord1: Coordinate, coord2: Coordinate): Boolean {
TODO("Some business logic here")
}
}
}
But in reality this doesn't work. I could remove remove the filter method from the interface but that just defeats the point of the whole exercise. I have tried using varargs but again that's not resolving the issue as each override must implement varargs which is just not helpful. I know this may seem redundant, but is there a possibility to have the type of abstraction that I'm asking for? Or am I missing a point of an Interface?
Let's think about it a little. The main point of abstraction is that we can use Filter no matter what is the implementation. We don't need to know implementations, we only need to know interfaces. But how could we use Filter if we don't know what data has to be provided to filter? We would need to use LocationFilter directly which also defeats the point of creating an interface.
Your problem isn't really related to Kotlin, but to OOP in general. In most languages it is solved by generics/templates/parameterized types. It means that an interface/class is parameterized by another type. You use it in Kotlin like this:
interface Filter<in T> {
fun filter(value: T): Boolean
}
object LocationFilter : Filter<Coordinate> {
override fun filter(value: Coordinate): Boolean {
TODO()
}
}
fun acquireCoordinateFilter(): Filter<Coordinate> = LocationFilter
fun main() {
val coord: Coordinate = TODO()
val filter: Filter<Coordinate> = acquireCoordinateFilter()
val result = filter.filter(coord)
}
Filter is parameterized, meaning that we can have a filter for filtering strings (type is: Filter<String>), for filtering integers (Filter<Int>) or for filtering coordinates (Filter<Coordinate>). Then we can't use e.g. Filter<String> to filter integers.
Note that the code in main() does not use LocationFilter directly, it only knows how to acquire Filter<Coordinate>, but the specific implementation is abstracted from it.
Also note there is already a very similar interface in Java stdlib. It is called Predicate.
my interpretation of this is that the input doesn't need to be specified.
Where did you get that interpretation from?
You can see that it can't be correct, by looking at how the method would be called. You should be able to write code that works for any instance of Filter — and that can only happen if the number and type of argument(s) is specified in the interface. To use your example:
val f: Filter = someMethodReturningAFilterInstance()
val result = f.filter(coord1, coord2)
could only work if all implementations used two Coordinate parameters. If some used one String param, and others used nothing at all, then how would you call it safely?
There are a few workarounds you could use.
If every implementation takes the same number of parameters, then you could make the interface generic, with type parameter(s), e.g.:
interface Filter<T1, T2> {
fun filter(t1: T1, t2: T2): Boolean
}
Then it's up to the implementation to specify which types are needed. However, the calling code either needs to know the types of the particular implementation, or needs to be generic itself, or the interface needs to provide type bounds with in variance.
Or if you need a variable number of parameters, you could bundle them up into a single object and pass that. However, you'd probably need an interface for that type, in order to handle the different numbers and types of parameters, and/or make that type a type parameter on Filter — all of which smells pretty bad.
Ultimately, I suspect you need to think about how your interface is going to be used, and in particular how its method is going to be called. If you're only ever going to call it when the caller knows the implementation type, then there's probably no point trying to specify that method in the interface (and maybe no point having the interface at all). Or if you'll want to handle Filter instances without knowing their concrete type, then look at how you'll want to make those calls.
The whole this is wrong!
First, OOP is a declarative concept, but in your example the type Filter is just a procedure wrapped in an object. And this is completely wrong.
Why do you need this type Filter? I assume you need to get a collection filtered, so why not create a new object that accepts an existing collection and represents it filtered.
class Filtered<T>(private val origin: Iterable<T>) : Iterable<T> {
override fun iterator(): Iterator<T> {
TODO("Filter the original iterable and return it")
}
}
Then in your code, anywhere you can pass an Iterable and you want it to be filtered, you simply wrap this original iterable (any List, Array or Collection) with the class Filtered like so
acceptCollection(Filtered(listOf(1, 2, 3, 4)))
You can also pass a second argument into the Filtered and call it, for example, predicate, which is a lambda that accepts an element of the iterable and returns Boolean.
class Filtered<T>(private val origin: Iterable<T>, private val predicate: (T) -> Boolean) : Iterable<T> {
override fun iterator(): Iterator<T> {
TODO("Filter the original iterable and return it")
}
}
Then use it like:
val oddOnly = Filtered(
listOf(1, 2, 3, 4),
{ it % 2 == 1 }
)
I am trying to use the public interface Function (as I learned it in Java) in Kotlin.
For this I created my method
fun foo(input: List<String>, modifier1: Function<List<String>>? = null){
}
as far I remember here I should be able to do modifier1.apply(input)
but seems like it is not possible (it is possible to do modifier1.apply{input} though)
Reading more about it I found this:
Kotlin: how to pass a function as parameter to another?
So I changed my method signature to this:
fun foo(input:String, modifier2: (List<String>) -> (List<String>){
}
Here I am able to do modifier2(input)
and I can call foo this way
service.foo(input, ::myModifierFunction)
where
fun myModifierFunction(input:List<String>):List<String>{
//do something
return input
}
So far this seems possible but it is not acceptable to have the function reference as nullable, is there any way I can do that? or use Function ?
You were using kotlin.Function instead of java.util.function.Function in your first example. Note that the latter takes 2 generic types: 1 for the incoming parameter and 1 for the resulting one.
The apply method you saw is the default Kotlin one: apply, not the one of Java's Function-interface.
If you really want to have the Java-function as nullable type the following should work:
fun foo(input: List<String>, modifier1: java.util.function.Function<List<String>, List<String>>? = null) {
modifier1?.apply(input) ?: TODO("what should be done if there wasn't passed any function?")
}
Kotlin variant for the same:
fun foo(input: List<String>, modifier1: ((List<String>) -> List<String>)? = null) {
modifier1?.invoke(input) ?: TODO("what should be done if there wasn't passed any function?")
}
Maybe also a default function, such as { it } instead of null might better suite your needs? (Java variant would be Function.identity()):
// java modifier1 : Function<List<String>, List<String>> = Function.identity()
// kotlin modifier1 : (List<String>) -> List<String> = { it }
You can make the reference nullable simply with ? — the only wrinkle is that the whole function type needs to be in parens first:
fun foo(input: String, modifier2: ((List<String>) -> List<String>)? = null) {
}
As required, modifier2 is optional; if specified, it may contain null, or it may contain a function taking and returning a list of strings.
As mentioned in another answer, kotlin.Function is not the same as java.util.function.Function — though in practice you shouldn't need to refer to either directly, as the -> notation is simpler.
If you want to pass in a function that takes List<String> as its parameter and returns nothing meaningful, the type for you is Function1<List<String>, Unit>. The method name for invoking a function is invoke(), which you could also do with just regular parentheses, if it wasn't nullable. All in all, your code could look something like this:
fun foo(input: List<String>, modifier1: Function1<List<String>, Unit>? = null) {
modifier1?.invoke(input)
}
The 1 in the typename of Function1 means that it's a one parameter function, there's also Function0, Function2, etc.
The Function type on its own is not something you can use to call that function, as it's an empty marker interface. All functions implement this regardless of how many parameters they have.
coming across a sample with a class and a function and trying to understand the koltin syntax there,
what does this IMeta by dataItem do? looked at https://kotlinlang.org/docs/reference/classes.html#classes and dont see how to use by in the derived class
why the reified is required in the inline fun <reified T> getDataItem()? If someone could give a sample to explain the reified?
class DerivedStreamItem(private val dataItem: IMeta, private val dataType: String?) :
IMeta by dataItem {
override fun getType(): String = dataType ?: dataItem.getType()
fun getData(): DerivedData? = getDataItem()
private inline fun <reified T> getDataItem(): T? = if (dataItem is T) dataItem else null
}
for the reference, copied the related defines here:
interface IMeta {
fun getType() : String
fun getUUIDId() : String
fun getDataId(): String?
}
class DerivedData : IMeta {
override fun getType(): String {
return "" // stub
}
override fun getUUIDId(): String {
return "" // stub
}
override fun getDataId(): String? {
return "" // stub
}
}
why the reified is required in the inline fun <reified T> getDataItem()? If someone could give a sample to explain the reified?
There is some good documentation on reified type parameters, but I'll try to boil it down a bit.
The reified keyword in Kotlin is used to get around the fact that the JVM uses type erasure for generic. That means at runtime whenever you refer to a generic type, the JVM has no idea what the actual type is. It is a compile-time thing only. So that T in your example... the JVM has no idea what it means (without reification, which I'll explain).
You'll notice in your example that you are also using the inline keyword. That tells Kotlin that rather than call a function when you reference it, to just insert the body of the function inline. This can be more efficient in certain situations. So, if Kotlin is already going to be copying the body of our function at compile time, why not just copy the class that T represents as well? This is where reified is used. This tells Kotlin to refer to the actual concrete type of T, and only works with inline functions.
If you were to remove the reified keyword from your example, you would get an error: "Cannot check for instance of erased type: T". By reifying this, Kotlin knows what actual type T is, letting us do this comparison (and the resulting smart cast) safely.
(Since you are asking two questions, I'm going to answer them separately)
The by keyword in Kolin is used for delegation. There are two kinds of delegation:
1) Implementation by Delegation (sometimes called Class Delegation)
This allows you to implement an interface and delegate calls to that interface to a concrete object. This is helpful if you want to extend an interface but not implement every single part of it. For example, we can extend List by delegating to it, and allowing our caller to give us an implementation of List
class ExtendedList(someList: List) : List by someList {
// Override anything from List that you need
// All other calls that would resolve to the List interface are
// delegated to someList
}
2) Property Delegation
This allows you to do similar work, but with properties. My favorite example is lazy, which lets you lazily define a property. Nothing is created until you reference the property, and the result is cached for quicker access in the future.
From the Kotlin documentation:
val lazyValue: String by lazy {
println("computed!")
"Hello"
}