为什么在 Scala 中向后使用 concat 运算符?
Why do you use concat operator backward in scala?
在 Scala 中 repl
scala> List(1) :: 2
<console>:8: error: value :: is not a member of Int
List(1) :: 2
但是
scala> 2 :: List(1);
res4: List[Int] = List(2, 1)
这是违反直觉的,因为如果从左到右阅读中缀运算符,则上面的行可以转换为
List(1) :: 2
List(1).::(2)
和
2 :: List(1)
2.::(List(1))
我想 Int
没有方法 ::
而 List
有。我是不是猜错了?
以 :
结尾的 Scala 运算符是右结合的。因此,在您的示例中,您正在尝试将 ::
运算符应用于 Int
.
此外,List
结构在 Scala 中是不可变的,因此追加到列表的末尾非常昂贵;将值添加到列表的开头非常便宜。
This is counter intuitive since if infix operators are read left to
right
如果你仔细想想,从逻辑上讲,这是很有道理的。 ::
(缺点)运算符 prepends 值到列表的开头,它不会 append 它到结尾名单。当您这样想时,::
运算符是右结合的事实是有道理的,因为它将一个元素粘贴到 List
:
的开头
scala> 4 :: List(3,2,1)
res1: List[Int] = List(4, 3, 2, 1)
内部实现比较简单:
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
List
在内部实现为一个 LinkedList,它包含一个头(集合中的第一个元素)和一个剩余元素列表(尾部)。这就是为什么前置元素比附加元素便宜得多,因为它需要对内部列表进行 O(n) 遍历才能复制元素,并附加新值。
虽然昂贵,但您仍然可以使用 :+
运算符来实现,它是 左结合:
scala> List(1,2,3) :+ 4
res3: List[Int] = List(1, 2, 3, 4)
在 Scala 中 repl
scala> List(1) :: 2
<console>:8: error: value :: is not a member of Int
List(1) :: 2
但是
scala> 2 :: List(1);
res4: List[Int] = List(2, 1)
这是违反直觉的,因为如果从左到右阅读中缀运算符,则上面的行可以转换为
List(1) :: 2
List(1).::(2)
和
2 :: List(1)
2.::(List(1))
我想 Int
没有方法 ::
而 List
有。我是不是猜错了?
以 :
结尾的 Scala 运算符是右结合的。因此,在您的示例中,您正在尝试将 ::
运算符应用于 Int
.
此外,List
结构在 Scala 中是不可变的,因此追加到列表的末尾非常昂贵;将值添加到列表的开头非常便宜。
This is counter intuitive since if infix operators are read left to right
如果你仔细想想,从逻辑上讲,这是很有道理的。 ::
(缺点)运算符 prepends 值到列表的开头,它不会 append 它到结尾名单。当您这样想时,::
运算符是右结合的事实是有道理的,因为它将一个元素粘贴到 List
:
scala> 4 :: List(3,2,1)
res1: List[Int] = List(4, 3, 2, 1)
内部实现比较简单:
def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)
List
在内部实现为一个 LinkedList,它包含一个头(集合中的第一个元素)和一个剩余元素列表(尾部)。这就是为什么前置元素比附加元素便宜得多,因为它需要对内部列表进行 O(n) 遍历才能复制元素,并附加新值。
虽然昂贵,但您仍然可以使用 :+
运算符来实现,它是 左结合:
scala> List(1,2,3) :+ 4
res3: List[Int] = List(1, 2, 3, 4)