为什么“++”有效但“::”无效,即使它们在 Scala 中具有相同的逻辑

Why "++" works but "::" doesn't work even though they have same logic in scala

abstract class MyList[+A] {
    def head: A
    def next: MyList[A]
    def isEmpty: Boolean
    def add[B >: A](element: B): MyList[B]
    def printElements: String
    override def toString: String = s"[$printElements]"
    def ++[B >: A](list: MyList[B]): MyList[B]
    def ::[B >: A](list: MyList[B]): MyList[B]
}

case object Empty extends MyList[Nothing] {
    def head: Nothing = throw new NoSuchElementException
    def next: MyList[Nothing] = throw new NoSuchElementException
    def isEmpty: Boolean = true
    def add[B >: Nothing](element: B): MyList[B] = Cons(element, Empty)
    def printElements: String = ""
    def ++[B >: Nothing](list: MyList[B]): MyList[B] = list
    def ::[B >: Nothing](list: MyList[B]): MyList[B] = list
}

case class Cons[+A](h: A, t: MyList[A]) extends MyList[A] {
    def this(h: A) = this(h, Empty)
    def head: A = h
    def next: MyList[A] = t
    def isEmpty: Boolean = false
    def add[B >: A](element: B): MyList[B] = Cons(element, this)
    def printElements: String =
        if (t.isEmpty) s"$h"
        else s"$h ${t.printElements}"

    def ++[B >: A](list: MyList[B]): MyList[B] = Cons(h, next ++ list)
    def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, next :: list)
}

object runTest extends App {
    val a = Empty.add(1).add(2).add(3)
    val b = Empty.add(4).add(5).add(6)
    println(a)
    println(b)
    println(a ++ b) //[3 2 1 6 5 4] good
    println(a :: b) //[6 3 5 2 4 1] why???
}

我尝试连接两个 MyList,但问题是, “++”和“::”逻辑相同 但是“++”将打印 [3 2 1 6 5 4],这是有道理的,而“::”将打印 [6 3 5 2 4 1]

来自2.13 language specifications(我好像找不到scala3版本,不过这部分没变):

Operators ending in a colon ‘:’ are right-associative. All other operators are left-associative.

[...]

If op is right-associative and its parameter is passed by name, the same operation is interpreted as e2.op(e1)


所以你的 a :: bb.::(a) 相同,

def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, next :: list)

def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, list.::(next))

这解释了您得到的 [6 3 5 2 4 1]

您可以使用

得到您想要的结果
def ::[B >: A](list: MyList[B]): MyList[B] = Cons(h, next.::(list))
...
println(a.::(b))