观心静

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

前言

我们经常在Kotlin中看到operator关键字,它用于重载操作符或者定义一些特定的函数,这些函数有预定义的名称(如plus、get等)。

在Android开发中,operator的使用场景包括但不限于:

  1. 重载算术运算符(如+、-、*、/等)或者比较运算符(如==、>、<等)。

  2. 重载下标操作符([]),用于像访问数组一样访问对象。

  3. 重载范围操作符(..),用于创建区间。

  4. 重载in操作符,用于判断某个对象是否在集合中。

  5. 重载解构声明(componentN函数)。

  6. 重载调用操作符(invoke),使得对象可以像函数一样调用。

 

例子

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity

// 1. 重载算术运算符
data class Position(val x: Int, val y: Int) {
    operator fun plus(other: Position) = Position(x + other.x, y + other.y)
}

// 2. 重载索引访问
class Matrix(private val data: Array<IntArray>) {
    operator fun get(row: Int, col: Int) = data[row][col]
    operator fun set(row: Int, col: Int, value: Int) {
        data[row][col] = value
    }
}

// 3. 重载比较运算符
class Timestamp(val milliseconds: Long) {
    operator fun compareTo(other: Timestamp) = milliseconds.compareTo(other.milliseconds)
}

// 4. 重载invoke操作符
class ClickListener {
    operator fun invoke(viewId: Int) = Log.d("Operator", "View $viewId clicked")
}

// 5. 重载rangeTo操作符
class DateRange(val start: String, val end: String) {
    operator fun rangeTo(other: String) = DateRange(start, other)
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 使用重载的运算符
        val pos1 = Position(10, 20)
        val pos2 = Position(5, 5)
        val pos3 = pos1 + pos2  // 调用plus
        Log.d("Operator", "Position: ${pos3.x},${pos3.y}")

        // 矩阵索引操作
        val matrix = Matrix(arrayOf(intArrayOf(1, 2), intArrayOf(3, 4)))
        val element = matrix[1, 0]  // 调用get
        matrix[0, 1] = 99           // 调用set
        Log.d("Operator", "Matrix element: $element")

        // 日期范围
        val range = DateRange("2023-01-01").."2023-12-31"
        Log.d("Operator", "Date range: ${range.start} to ${range.end}")

        // 时间戳比较
        val time1 = Timestamp(System.currentTimeMillis() - 1000)
        val time2 = Timestamp(System.currentTimeMillis())
        Log.d("Operator", "Time comparison: ${time1 < time2}")  // 调用compareTo

        // 调用操作符
        val clickListener = ClickListener()
        clickListener(123)  // 相当于clickListener.invoke(123)
    }
}

invoke例子

import android.os.Bundle
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity

// 1. 基本invoke操作符
class Calculator {
    operator fun invoke(a: Int, b: Int): Int = a + b
}

// 2. 带接收者的invoke
class ButtonHandler {
    operator fun Button.invoke() {
        this.text = "Clicked!"  // 使用Button的扩展方法
    }
}

// 3. DSL风格的invoke
class DialogBuilder {
    fun title(text: String) = apply { println("Setting title: $text") }
    fun message(text: String) = apply { println("Setting message: $text") }
    
    operator fun invoke(block: DialogBuilder.() -> Unit) {
        block()
        println("Dialog shown")
    }
}

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 示例1: 基础invoke用法
        val calculator = Calculator()
        val result = calculator(3, 5)  // 相当于调用calculator.invoke(3,5)
        println("Calculator result: $result")
        
        // 示例2: 按钮点击处理的invoke
        val buttonHandler = ButtonHandler()
        val button = Button(this).apply {
            setOnClickListener { 
                buttonHandler(this)  // 调用按钮扩展方法
            }
        }
        
        // 示例3: DSL风格的对话框构建
        val dialog = DialogBuilder()
        dialog {  // 调用invoke操作符
            title("Welcome")
            message("Hello World!")
        }
        
        // 示例4: lambda作为invoke参数
        val callback: (String) -> Unit = { message -> 
            println("Callback received: $message")
        }
        callback("Hello from invoke!")  // 调用lambda的invoke
    }
}

 

 

 

end

 

posted on 2025-08-07 11:23  观心静  阅读(67)  评论(0)    收藏  举报