2013-09-24 83 views
12

Gần đây tôi đã đọc về hành vi của GStringImpl s so với String khi được sử dụng trong bộ sưu tập trong Groovy.Groovy GStringImpl và hành vi chuỗi

Tôi hiểu rằng lý do này là false ...

"${'test'}".equals("test") == false

là do sự yêu cầu đối xứng của hợp đồng .equals(), tuy nhiên tôi đã tự hỏi nếu có một lý do không thể GStringImpl chỉ được đánh giá là String ngay lập tức. Vì vậy, khi tôi làm điều gì đó như thế này ...

"${'someString'}"

Tôi không nhận được một GStringImpl, tôi chỉ nhận được một đồng bằng Java String trở lại, mà tôi ngay lập tức có thể sử dụng như là chìa khóa trong một bản đồ, ví dụ .

Tôi biết có một số cách giải quyết, như

String s = "${'someString'}"

tuy nhiên những thứ như thế này là một chút bất tiện, và mixup giữa GStringImplString có vẻ là một lớn 'Gotcha' cho newbees Groovy.

Trả lời

15

GStrings không được đánh giá ngay lập tức cho chuỗi vì một số lý do, chủ yếu liên quan đến đánh giá lười (khá tốt cho việc ghi nhật ký) và tạo mẫu. Trong Strings and GString bạn có thể tìm thấy một lời giải thích tốt:

GString có thể liên quan đến đánh giá lười biếng vì vậy nó không cho đến khi toString() phương pháp được gọi là G-string được đánh giá. Đánh giá lười biếng này rất hữu ích cho những thứ như ghi nhật ký vì nó cho phép tính toán chuỗi , các cuộc gọi đến toString() trên các giá trị và nối các của các chuỗi khác nhau được thực hiện một cách lười biếng nếu có.

GString khá tiện dụng khi bạn không muốn sử dụng công cụ mẫu, hoặc khi bạn thực sự muốn đánh giá đầy đủ về GStrings. Khi một số biến số được nhúng trong GString, hàm toString() được gọi trên biến số để có được biểu diễn chuỗi và được chèn vào chuỗi cuối cùng .

Do đó:

G-string và String hai lớp riêng biệt, và do đó việc sử dụng G-string đối tượng như là chìa khóa cho các đối tượng Map hoặc so sánh liên quan đến G-string đối tượng, có thể tạo ra kết quả bất ngờ khi kết hợp với String các đối tượng từ một GString và một String sẽ không có cùng một hashCode cũng như chúng sẽ bằng nhau. Không có sự ép buộc tự động giữa hai loại để so sánh hoặc khóa bản đồ, vì vậy đôi khi cần phải gọi toString() một cách rõ ràng trên các đối tượng GString.

Chuyển đổi không mong muốn thành Chuỗi có thể dẫn đến sự cố khi mã là mong đợi một GString, cũng như đối với các phương thức trong các lớp groovy.sql.

+0

Đủ công bằng. Cảm ơn lời giải thích. – rcgeorge23

+0

Chúng tôi có thể tự động mở rộng lớp GStringImpl để tự động gọi .toString() khi xây dựng không? –