【问题标题】:Kotlin - collection plus() × plusElement() differenceKotlin - 集合 plus() × plusElement() 的区别
【发布时间】:2019-05-07 01:59:46
【问题描述】:

在实践中,plusplusElementminusminusElement)函数与(不可变的)List 有什么区别?

operator fun <T> Collection<T>.plus(element: T): List<T>

fun <T> Collection<T>.plusElement(element: T): List<T>

【问题讨论】:

  • 语法coll + element 是不同的,我想说。

标签: list collections kotlin


【解决方案1】:

除了plusminusoperators,因此可以分别简化为+-,我想分享一个例子,这可能会更清楚,为什么plusElementminusElement使用也可能有意义。基本上,当您不希望调用重载的运算符方法时(例如plus(elements : Iterable&lt;T&gt;))就是这种情况,当您处理列表列表时可能就是这种情况。

也许以下示例可以更清楚地说明这一点。在示例中,所有变量分配都显示了它们在调用相应函数时分配的类型,并将结果包含在行尾的注释中。变量 ~ending 命名约定如下:

  • PlusT 显示对plus(element : T) 的调用
  • PlusIterable 显示对plus(elements : Iterable&lt;T&gt;) 的调用
  • PlusElementT 显示呼叫plusElement(element : T)

样品:

val someEntry = "some entry"
val listOfSomeEntry = listOf(someEntry)

val los : List<String> = listOf("listOfString")
val lsPlusT         : List<String> = los.plus(someEntry)               // [listOfString, some entry]
val lsPlusIterable1 : List<String> = los.plus(listOfSomeEntry)         // [listOfString, some entry]
val lsPlusIterable2 : List<Any>    = los.plus(listOf(listOfSomeEntry)) // [listOfString, [some entry]]
val lsPlusElementT1 : List<String> = los.plusElement(someEntry)        // [listOfString, some entry]
val lsPlusElementT2 : List<Any>    = los.plusElement(listOfSomeEntry)  // [listOfString, [some entry]]

val lol : List<List<String>> = listOf(listOf("listOfList"))
// the following is basically not really correct as we are now dealing with a list of lists of strings, but it shows that llPlusT and llPlusIterable lead to the same (in this case probably wrong) result..
val llPlusT         : List<Any>          = lol.plus(someEntry)               // [[listOfList], some entry]
val llPlusIterable  : List<Any>          = lol.plus(listOfSomeEntry)         // [[listOfList], some entry]
val llPlusIterable2 : List<List<String>> = lol.plus(listOf(listOfSomeEntry)) // [[listOfList], [some entry]]
val llPlusElement1  : List<Any>          = lol.plusElement(someEntry)        // [[listOfList], some entry]
val llPlusElement2  : List<List<String>> = lol.plusElement(listOfSomeEntry)  // [[listOfList], [some entry]]

正如您在使用 + 时看到的那样,可能会使用重载变体 plus(elements : Iterable&lt;T&gt;),这在大多数情况下可能有意义,但在其他一些情况下可能没有意义,例如(大多数时候)在处理列表列表时。与其强制+ 使用+ listOf(anotherList) 添加列表列表,不如使用plusElement (plusElement(anotherList)),或者如果您确定只想添加一个元素,您可能想要省略 plus 以支持 plusElement (可能是一个非常罕见且非常特殊的用例......这将通过变体 llPlusElement1 反映出来)。

最后,plusElementminusElement 从命名中非常清楚地表明,您传递的内容反映了列表中的一项,而 + 基本上是开放的...(但是您应该从上下文,其中带有列表的列表可能并不那么清楚;-))。最后还有一个免责声明:这不意味着您应该使用列表列表,但以防万一您发现类似的东西,您手头有 plus/minusElement ;-)

【讨论】:

    【解决方案2】:

    第一个是重载运算符,如operator 关键字所示。它允许您将+ 运算符与List&lt;T&gt; 一起使用。

    第二个是普通函数,以普通函数调用方式调用。

    两者都返回一个新的List&lt;T&gt;,并附加了element

    来自 Kotlin REPL 的抄本:

    >>>val a = listOf(1, 2, 3)
    >>>a + 4
    [1, 2, 3, 4]
    >>> a.plusElement(4)
    [1, 2, 3, 4]
    

    有关 Kotlin 运算符重载的更多信息,请参阅https://kotlinlang.org/docs/reference/operator-overloading.html

    【讨论】:

    • 这是错误的。 plus() 是运算符重载这一事实并不能解释差异(您也可以简单地显式调用.plus() pl.kotl.in/FhQgoIgtx >)。 @Roland 的回答是正确的,真正的区别是,如果你有集合的集合,那么plus() 函数调用可能有两种解释。 plusElement() 函数提供了一种强制将列表添加到列表列表的方法,而不是单独添加其元素。
    猜你喜欢
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 2013-10-24
    相关资源
    最近更新 更多