对理解lambda和接收器的困惑

时间:2018-10-07 12:31:46

标签: lambda kotlin extension-function

kotlin 1.2.50

我一直在youtube https://www.youtube.com/watch?v=gPH9XnvpoXE上关注本教程的一些示例。我已经了解了几件事,但是仍然有些困惑。我已将注释留在下面的代码中,我不确定发生了什么。

 add_filter( 'user_has_cap',   'give_permissions'  , 10, 3 );

 function give_permissions( $allcaps, $cap, $args ) {

    if ( isset( $cap[0] ) && $cap[0] == 'view_order' ) {
        $get_additional_ids = get_user_meta( get_current_user_id(), 'additional_orders', false );
        if ( isset( $get_additional_ids[0] ) && in_array( $args[2], $get_additional_ids[0] ) ) {
            $allcaps[ $cap[0] ] = true;
        }
    }
    return ( $allcaps );
}

在此先感谢

2 个答案:

答案 0 :(得分:8)

  

/ *我们要传递lambda和接收器吗?接收者将是什么* /

     

私人乐趣JavaClientBuilder.twitter(供应商:JavaTwitterBuilder。()->单位)

我们确实在此函数中有一个接收器,并且将在JavaClientBuilder的实例上调用此函数。

  

/ *我们称为JavaTwitterBuilder()。apply(..)将应用返回新创建的对象吗?不知道为什么我们必须在apply * /

中通过供应商      

twitter = JavaTwitterBuilder()。apply(suppler).build()

要了解apply()的工作原理,请查看其源代码(简化版):

public inline fun <T> T.apply(block: T.() -> Unit): T {
    block()
    return this
}

这是在类型T的接收器上声明的扩展函数,并返回T的实例,该实例包含一个块-另一个类型为T的接收器的扩展函数返回{{ 1}}。它通常用于替换Bu​​ilder模式-将自定义初始化逻辑应用于对象。在您的情况下,Unit是一个包含suppler实例的初始化逻辑的块。功能代码创建实例,并使用JavaTwitterBuilderapply()中的逻辑来初始化该实例。

  

/ *我们是否传递了不返回任何内容的lambda和接收器* /

     

私人乐趣createClient(供应商:JavaClientBuilder。()->单位):JavaClient

在这种情况下,suppler没有接收器,它是顶级功能。

  

/ *混乱:不确定,因为我们称供应商。奇怪的是,上面的javaClient {} lambda * /

中调用了JavaClientBuilder      

javaClientBuilder.suppler()

createClient()是一个lambda,其中suppler是接收者类型,这使我们可以在新创建的JavaClientBuilder实例上调用它。

  

/ *我理解这一点,这是一个扩展函数,它格式化并从* /

上调用的JavaClient对象返回字符串      

priv val JavaClient.toConsole:字符串       get()=           “创建的客户端是:$ {twitter.handle} $ {company.name}”

对!只是一个小的更正,它是一个扩展属性。属性可以具有自定义的getter和setter。该属性定义了一个自定义的getter,因此实际上,每当访问此属性时,它都会产生一个具有getter代码描述的格式的String。

答案 1 :(得分:2)

希望以下示例有助于理解具有接收器类型的 lambda:

data class Person(val name: String)

fun getPrefixSafely(
    prefixLength: Int,
    person: Person?,
    getPrefix: Person.(Int) -> String): String
{
    if (person?.name?.length ?: 0 < prefixLength) return ""
    return person?.getPrefix(prefixLength).orEmpty()
}

// Here is how getPrefixSafely can be called
getPrefixSafely(
    prefixLength = 2,
    person = Person("name"),
    getPrefix = { x -> this.name.take(x) }
)

PS:这些具有接收器类型的函数文字类似于 IMO 的扩展函数。