Cả hai chức năng f1
và f2
đều rất giống nhau. Nếu bạn xuất bytecode, bạn sẽ xem tối đa trong các hằng số hồ bơi mà họ được biểu hiện như:
#71 = Methodref #12.#70 // Main$.f2:(LMain$Animal;)Ljava/lang/String;
#74 = Methodref #12.#73 // Main$.f1:(LMain$Animal;)Ljava/lang/String;
Theo như các bytecode là có liên quan, họ là những chức năng mà phải mất một Animal
như một tham số và trả lại String
.
Một trường hợp điều này trở nên thú vị hơn là khi bạn muốn trả lại một số T
cụ thể (trong đó T <: Animal
). Hãy ghi nhớ, các bytecode vẫn sẽ giống nhau, nhưng tại thời gian biên dịch này cho biết thêm ý nghĩa và sức mạnh để tham số T
loại:
Hãy tưởng tượng bạn có:
def f1[T <: Animal](a: T): T = a // silly, I know
def f2(a: Animal): Animal = a
Và bạn thử điều này:
val s: Dog = f1(new Dog())
val t: Dog = f2(new Dog()) // NOPE
val u: Dog = f2(new Dog()).asInstanceOf[Dog] // awkward
Dòng thứ hai đó sẽ không biên dịch mà không truyền, hy sinh việc kiểm tra kiểu biên dịch.
Nếu 'f1' cần thiết để trả về một' T' hoặc một số loại mà tham chiếu 'T ', sau đó chắc chắn. –