2011-07-02 57 views
38

Trong REPL, tôi định nghĩa một hàm. Lưu ý kiểu trả về.Chuỗi Scala vs java.lang.String - kiểu suy luận

scala> def next(i: List[String]) = i.map {"0" + _} ::: i.reverse.map {"1" + _} 
next: (i: List[String])List[java.lang.String] 

Và nếu tôi xác định kiểu trả về như String

scala> def next(i: List[String]): List[String] = i.map {"0" + _} ::: i.reverse.map {"1" + _} 
next: (i: List[String])List[String] 

Tại sao sự khác biệt? Tôi cũng có thể chỉ định kiểu trả về là List [Any], vì vậy tôi đoán String chỉ là một siêu kiểu bao bọc cho java.lang.String. Điều này sẽ có bất kỳ ý nghĩa thực tế hoặc tôi có thể an toàn không chỉ định kiểu trả về?

Trả lời

52

Đây là một câu hỏi rất hay! Trước tiên, hãy để tôi đảm bảo với bạn rằng bạn có thể chỉ định kiểu trả về một cách an toàn.

Bây giờ, hãy nhìn vào nó ... có, khi để suy luận, Scala infers java.lang.String, thay vì chỉ String. Vì vậy, nếu bạn tra cứu "Chuỗi" trong số ScalaDoc, bạn sẽ không tìm thấy bất kỳ thứ gì, điều này dường như chỉ ra rằng đó không phải là một lớp Scala. Vâng, nó phải đến từ đâu đó, mặc dù.

Hãy xem xét nhập Scala theo mặc định. Bạn có thể tìm thấy nó bằng chính mình trên REPL:

scala> :imports 
1) import java.lang._    (155 types, 160 terms) 
2) import scala._     (801 types, 809 terms) 
3) import scala.Predef._   (16 types, 167 terms, 96 are implicit) 

Hai đầu tiên là gói - và, quả thật vậy, String có thể được tìm thấy trên java.lang! Vậy thì sao? Hãy kiểm tra bằng cách instantiating cái gì khác từ gói đó:

scala> val s: StringBuffer = new StringBuffer 
s: java.lang.StringBuffer = 

scala> val s: String = new String 
s: String = "" 

Vì vậy, điều đó dường như không phải vậy. Bây giờ, nó không thể nằm trong gói scala, hoặc nó sẽ được tìm thấy khi nhìn lên ScalaDoc. Vì vậy, hãy nhìn vào bên trong scala.Predef, và ở đó!

type String = String 

Điều đó có nghĩa là một Stringalias cho java.lang.String (được nhập khẩu trước đó). Trông giống như một tài liệu tham khảo theo chu kỳ mặc dù, nhưng nếu bạn đánh dấu vào source, bạn sẽ thấy nó được xác định với đường dẫn đầy đủ:

type String  = java.lang.String 

Tiếp theo, bạn có thể muốn hỏi tại sao? Vâng, tôi không có bất kỳ ý tưởng, nhưng tôi nghi ngờ nó là làm cho một lớp quan trọng như vậy một chút ít phụ thuộc vào JVM.

+0

Đó là một chút kỳ quặc mà các chuỗi ký tự được suy ra là loại java.lang.String, khi có vẻ như chúng có thể được suy ra bằng loại String. Nhưng tốt đẹp để biết họ là chính xác cùng một điều. –

+0

@Luigi Đó là vì các chữ cái _are_ của loại java.lang.String. Thực sự không có suy luận ở đây - chúng là chữ. –

+2

Có lẽ câu trả lời rõ ràng nhất, tốt nhất, tốt nhất mà tôi từng thấy trên SO. Vì vậy, làm mới. Cảm ơn Daniel – jbnunn

Các vấn đề liên quan