Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to specify "own type" as return type in Kotlin

Tags:

kotlin

Is there a way to specify the return type of a function to be the type of the called object?

e.g.

trait Foo {     fun bar(): <??> /* what to put here? */ {         return this     } }  class FooClassA : Foo {     fun a() {} }  class FooClassB : Foo {     fun b() {} }  // this is the desired effect: val a = FooClassA().bar() // should be of type FooClassA a.a()                     // so this would work  val b = FooClassB().bar() // should be of type FooClassB b.b()                     // so this would work 

In effect, this would be roughly equivalent to instancetype in Objective-C or Self in Swift.

like image 875
Alfonso Avatar asked Apr 10 '15 15:04

Alfonso


People also ask

How do I specify return type in Kotlin?

Kotlin function return valuesTo return values, we use the return keyword. In the example, we have two square functions. When a funcion has a body enclosed by curly brackets, it returns a value using the return keyword. The return keyword is not used for functions with expression bodies.

Can we use class name as return type?

When a method uses a class name as its return type, the class of the type of the returned object must be either a subclass of, or the exact class of, the return type. Suppose that you have a class hierarchy in which ImaginaryNumber is a subclass of java.

What is the difference between return type Unit and return type nothing in Kotlin?

You use Unit as a return type in Kotlin when you would use void (lowercase v) in Java. The Nothing type has no values. If a function has return type Nothing , then it cannot return normally. It either has to throw an exception, or enter an infinite loop.

How do I create a generic function Kotlin?

Kotlin generic extension function example As extension function allows to add methods to class without inherit a class or any design pattern. In this example, we add a method printValue()to ArrayList class of generic type. This method is called form stringList. printValue() and floatList.


2 Answers

There's no language feature supporting this, but you can always use recursive generics (which is the pattern many libraries use):

// Define a recursive generic parameter Me trait Foo<Me: Foo<Me>> {     fun bar(): Me {         // Here we have to cast, because the compiler does not know that Me is the same as this class         return this as Me     } }  // In subclasses, pass itself to the superclass as an argument: class FooClassA : Foo<FooClassA> {     fun a() {} }  class FooClassB : Foo<FooClassB> {     fun b() {} } 
like image 126
Andrey Breslav Avatar answered Sep 30 '22 18:09

Andrey Breslav


You can return something's own type with extension functions.

interface ExampleInterface // Everything that implements ExampleInterface will have this method. fun <T : ExampleInterface> T.doSomething(): T {     return this }  class ClassA : ExampleInterface {     fun classASpecificMethod() {} }  class ClassB : ExampleInterface {     fun classBSpecificMethod() {} }  fun example() {     // doSomething() returns ClassA!     ClassA().doSomething().classASpecificMethod()     // doSomething() returns ClassB!     ClassB().doSomething().classBSpecificMethod() } 
like image 21
Patrick Avatar answered Sep 30 '22 16:09

Patrick