Kotlin骚气写法 三

ViewGroup获取ChildView集合
fun ViewGroup.asSequence(): Sequence<View> = (0..childCount).asSequence().map { getChildAt(it) }
inline noinline crossinline比较

参考:https://blog.csdn.net/u013009899/article/details/78584994
Kotlin代码

fun outterFun() {
    innerFun {
        return//支持直接返回outterFun
        return@innerFun 1 //如果要返回lambda,则必须有返回值
    }
    innerFun_ {
        //return//不支持直接返回outterFun
        return@innerFun_ 1 //如果要返回lambda,则必须有返回值
    }
    innerFun__ {
        //return//不支持直接返回outterFun
        return@innerFun__ 1 //如果要返回lambda,则必须有返回值
    }
    //以下lambada变换意义相同/总有一款你喜欢的
    foo(fun() {}, { "" })
    foo({}, { "" })
    foo(fun() = Unit, { "" })
    foo({}) { "" }//推荐

    //方式一 外部变量
    foo({ }, testNotInlined)

    //方式二 局部变量
    //如果是匿名或者具名函数,则支持
    var f = fun(): String? { return "MaQi" }
    foo({ }, f)
    foo({ }, innerFun___no())

    //方式三 函数传参
    innerFun___(fun(reult: String?) {
        //返回的Maqi将在该函数中被调用
    }, { "Maqi" })
    foo({ }, innerFun___({ reult -> }) { "Maqi" })
    //转换
    foo({}, innerFun___(fun(reult: String?) {
        //返回的Maqi将在该函数中被调用
    }, { "Maqi" }))

    //测试 crossinline
    val retsult = innerFun___c(fun(reult: String?): String? {
        //返回的Maqi将在该函数中被调用
        return reult
    }, { "" })
}

//没有inline,函数不能外部返回,即innerFun不能直接return
fun innerFun__(a: () -> Int) {}

//让函数允许非局部返回(外部返回)
inline fun innerFun(a: () -> Int) {}

//inline crossinline需要同时存在
inline fun innerFun_(crossinline a: () -> Int) {}

//noinline 修饰 该函数只能作为参数传递,不能外部申明,inline noinline需要同时存在
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> String?) {}

//方式一
var testNotInlined = fun(): String? {
    return ""
}

//方式二
fun innerFun___(): () -> String? {
    return testNotInlined
}

//方式三
inline fun innerFun___(callback: (reult: String?) -> Unit, notInlined: () -> String?): () -> String? {
    val string = notInlined()
    callback(string)
    return { string }
}

//可以发现 我们加上inlin后提示 noinline必须同时加上
//Can't inline 'notInlined' here: it may contain non-local returns. Add 'crossinline' modifier to parameter declaration 'notInlined'
//翻译以下大概意思是 函数当参数 有出现嵌套的情况下 我们必须让被套的那个不能提前return
//因为inline允许外部返回,即直接return,这样可能出现问题
inline fun innerFun___c(crossinline callback: (reult: String?) -> String?, crossinline notInlined: () -> String?): () -> String? {
    return { callback(notInlined()) }
}

inline fun innerFun___no(): () -> String? {
//Local functions are not yet supported in inline functions
//    return fun(): String? {
//        return ""
//    }
//如果是匿名或者具名函数,则支持
    return {""}
}

结论

  1. inline 修饰fun ,使函数可非局部返回
  2. crossinline 和 noinline 限制非局部返回,都只能修饰函数参数
  3. crossinline 或noinline存在时,inline 必须存在
  4. noinline 修饰的函数参数 只能在内联函数内部调用或者作为可内联的参数传递
  5. 它们貌似只会在代码编辑的时候提示,反编译Java代码没有什么特别,都是另外申明一个静态类继承Lambda 和实现invoke函数

如下为:testNotInlined 代码反编译示例

import kotlin.Metadata;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.internal.Lambda;
import org.jetbrains.annotations.Nullable;

@Metadata(bv = {1, 0, 3}, d1 = {"\u0000\b\n\u0000\n\u0002\u0010\u000e\n\u0000\u0010\u0000\u001a\u0004\u0018\u00010\u0001H\n¢\u0006\u0002\b\u0002"}, d2 = {"<no name provided>", "", "invoke"}, k = 3, mv = {1, 1, 13})
/* compiled from: Demo.kt */
final class DemoKt$testNotInlined$1 extends Lambda implements Function0<String> {
    public static final DemoKt$testNotInlined$1 INSTANCE = new DemoKt$testNotInlined$1();

    DemoKt$testNotInlined$1() {
        super(0);
    }

    @Nullable
    public final String invoke() {
        return "";
    }
}

非局部返回:直接在lambda返回外部函数

Kotlin 简化 Parcelable

在build gradle中申明

androidExtensions {
    experimental = true
}

@Parcelize 注解

@Parcelize
class Book(val title: String, val author: String, val year: Int) : Parcelable

参考Kotlin开发者:Parcelable, simplified
注意:文中指出存在兼容和继承的隐患,请谨慎使用

orEmpty()

String.kt 扩展函数

/** Returns the string if it is not `null`, or the empty string otherwise. */
@kotlin.internal.InlineOnly
public inline fun String?.orEmpty(): String = this ?: ""

当然还有很多很多骚操作,这里不一一列举。

kotlin 代理 关键字 by
@SuppressLint("ParcelCreator")
@Parcelize
data class TaskDetailArgs(val id: String) : Parcelable

private val args: TaskDetailArgs by args()
  
fun <V : Any> args() = object : ReadOnlyProperty<Fragment, V> {
    var value: V? = null

    override fun getValue(thisRef: Fragment, property: KProperty<*>): V {
        if (value == null) {
            val args = thisRef.arguments ?: throw IllegalArgumentException("There are no fragment arguments!")
            val argUntyped = args.get(“KEY_ARG”)
            argUntyped ?: throw IllegalArgumentException("arguments not found at key KEY_ARG!")
            @Suppress("UNCHECKED_CAST")
            value = argUntyped as V
        }
        return value ?: throw IllegalArgumentException("")
    }
}

kotlin List find

data class User(val name: String)
val data: List<User> = emptyList()
data.find { it.name == "MqQi" }
//等价于 
data.firstOrNull { it.name == "MqQi" }
TimingKt 获取执行时长
/**
 * Executes the given [block] and returns elapsed time in milliseconds.
 */
public inline fun measureTimeMillis(block: () -> Unit): Long {
    val start = System.currentTimeMillis()
    block()
    return System.currentTimeMillis() - start
}

使用

 val time = measureTimeMillis {}
Kotlin List 操作符重载

Collection.kt 扩展函数

/**
 * Returns a list containing all elements of the original collection and then the given [element].
 */
public operator fun <T> Collection<T>.plus(element: T): List<T> {
    val result = ArrayList<T>(size + 1)
    result.addAll(this)
    result.add(element)
    return result
}
 val list = listOf<String>() + "MQ"
repeat 重复执行
repeat(100) {
	Log.i("repeat", "repeat:$it")
}
startForegroundService
 @SuppressLint("NewApi")
    fun Service.setForegroundIfNecessary() {
        val exitIntent = Intent(this, ExitBroadcastReceiver::class.java).apply {
            action = "ACTION_TO_BACKGROUND"
        }
        val exitPendingIntent = PendingIntent.getBroadcast(this, 0, exitIntent, 0)

        val builder = NotificationCompat.Builder(this, "CHANNEL_NODE")
            .setContentTitle(getString(R.string.app_name))
            .setContentText(getString(R.string.background_connection_enabled))
            .setPriority(NotificationCompat.PRIORITY_MIN)
            .setWhen(0)
            .setDefaults(0)
            .setSound(null)
            .setDefaults(0)
            .setOnlyAlertOnce(true)
            .setColor(ContextCompat.getColor(this, R.color.gray_light))
            .setSmallIcon(R.drawable.ic_msg_default)
            .addAction(R.drawable.ic_close_black_24dp, getString(R.string.exit), exitPendingIntent)

        val pendingIntent = PendingIntent.getActivity(
            this, 0,
            MainActivity.getSingleIntent(this), 0
        )
        builder.setContentIntent(pendingIntent)

        supportsOreo {
            val channel = NotificationChannel(
                "CHANNEL_NODE",
                "Message_Node", NotificationManager.IMPORTANCE_LOW
            )
            channel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
            channel.setSound(null, null)
            channel.setShowBadge(false)
            notificationManager.createNotificationChannel(channel)
        }
        startForeground(66666, builder.build())
    }
    inline fun supportsOreo(code: () -> Unit) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            code()
        }
    }
    class ExitBroadcastReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent?) {
           
        }
    }
    companion object {
        fun startService(ctx: Context, action: String? = null) {
            val intent = Intent(ctx, MessageService::class.java).apply {
                this.action = action
            }
            ContextCompat.startForegroundService(ctx, intent)
        }

        fun stopService(ctx: Context) {
            val intent = Intent(ctx, MessageService::class.java)
            ctx.stopService(intent)
        }
    }

companion object {
        fun getSingleIntent(context: Context): Intent {
            return Intent(context, MainActivity::class.java).apply {
                addCategory(Intent.CATEGORY_LAUNCHER)
                addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
            }
        }
    }
vararg 关键字
fun addPlayer(game: Game, vararg players: Player):Deferred<List<PlayerStatus>>{
	players.forEach { player ->
             
           }
}

To be continue…

发布了141 篇原创文章 · 获赞 40 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_20330595/article/details/89349571