Invoke Operator & Operator Overloading in Kotlin

前端 未结 3 555
北海茫月
北海茫月 2020-12-30 23:39

I get to know about the Invoke operator that,

a() is equivalent to a.invoke()

Is there anything more regarding Invoke operator the

相关标签:
3条回答
  • 2020-12-31 00:06

    Yes, you can overload invoke. Here's an example:

    class Greeter(val greeting: String) {
        operator fun invoke(target: String) = println("$greeting $target!")
    }
    
    val hello = Greeter("Hello")
    hello("world")  // Prints "Hello world!"
    

    In addition to what @holi-java said, overriding invoke is useful for any class where there is a clear action, optionally taking parameters. It's also great as an extension function to Java library classes with such a method.

    For example, say you have the following Java class

    public class ThingParser {
        public Thing parse(File file) {
            // Parse the file
        }
    }
    

    You can then define an extension on ThingParser from Kotlin like so:

    operator fun ThingParser.invoke(file: File) = parse(file)
    

    And use it like so

    val parse = ThingParser()
    val file = File("path/to/file")
    val thing = parse(file)  // Calls Parser.invoke extension function
    
    0 讨论(0)
  • 2020-12-31 00:12

    If you have some Python background,

    you can think invoke in Kotlin as __call__ in Python.

    By using this, you can "call" your object as if it's a function.

    One difference is: you can overload invoke, but there is no official way to overload methods in Python.

    0 讨论(0)
  • 2020-12-31 00:13

    The most way to use a invoke operator is use it as a Factory Method, for example:

    //          v--- call the invoke(String) operator 
    val data1 = Data("1")
    
    //            v--- call the invoke() operator 
    val default = Data()
    
    //          v-- call the constructor
    val data2 = Data(2)
    

    This is because the companion object is a special object in Kotlin. Indeed, the code Data("1") above is translated to the code as below:

    val factory:Data.Companion = Data
    
    //                       v-- the invoke operator is used here
    val data1:Data = factory.invoke("1")
    

    class Data(val value: Int) {
    
        companion object {
            const val DEFAULT =-1
            //           v--- factory method
            operator fun invoke(value: String): Data = Data(value.toInt())
    
            //           v--- overloading invoke operator
            operator fun invoke(): Data = Data(DEFAULT)
        }
    }
    
    0 讨论(0)
提交回复
热议问题