Có gì sai với Chuỗi nhiều dòng Groovy?


105

Tập lệnh Groovy gây ra lỗi:

def a = "test"
  + "test"
  + "test"

Lỗi:

No signature of method: java.lang.String.positive() is 
applicable for argument types: () values: []

Mặc dù tập lệnh này hoạt động tốt:

def a = new String(
  "test"
  + "test"
  + "test"
)

Tại sao?


5
Trong trường hợp nó giúp người khác, bạn có thể gặp lỗi tương tự với mã như def a = b + + "/" + c. Trong trường hợp này, hai ký hiệu + rõ ràng là vấn đề.
Geoff Hackworth

Câu trả lời:


236

Vì Groovy không có điểm đánh dấu EOL (chẳng hạn như ;), nó sẽ bị nhầm lẫn nếu bạn đặt toán tử vào dòng sau

Điều này sẽ hoạt động thay thế:

def a = "test" +
  "test" +
  "test"

như trình phân tích cú pháp Groovy biết mong đợi điều gì đó ở dòng sau

Groovy coi bản gốc của bạn deflà ba tuyên bố riêng biệt. Điều đầu tiên chỉ định testcho a, hai thứ hai cố gắng làm cho "test"tích cực (và đây là nơi nó không thành công)

Với new Stringphương thức hàm tạo, trình phân tích cú pháp Groovy vẫn ở trong hàm tạo (vì dấu ngoặc nhọn chưa đóng), vì vậy nó có thể nối ba dòng với nhau thành một câu lệnh một cách hợp lý.

Đối với Chuỗi nhiều dòng thực sự, bạn cũng có thể sử dụng dấu ngoặc kép:

def a = """test
test
test"""

Sẽ tạo một chuỗi với thử nghiệm trên ba dòng

Ngoài ra, bạn có thể làm cho nó gọn gàng hơn bằng cách:

def a = """test
          |test
          |test""".stripMargin()

các stripMarginphương pháp sẽ cắt trái (lên đến và bao gồm các |char) từ mỗi dòng


6
Hoặc chỉ cần sử dụng dảiIndent () thay vì stripMargin().
sschuberth

Yeah, và bỏ qua các |ký tự trên dòng thêm
tim_yates

4
Bạn có thể sử dụng dấu ngoặc kép bên trong """chuỗi
tim_yates

3
Đúng vậy, tôi đã chỉnh sửa câu trả lời để hiển thị cách bạn sẽ cần định dạng lại một chút mã để stripIndent()hoạt động.
sschuberth

2
Bởi vì a) Tôi đã đăng nó như một bình luận, và b) Nó không khác nhiều so với câu trả lời này.
sschuberth 25/07/17

17

Bạn có thể nói với Groovy rằng câu lệnh sẽ đánh giá quá dòng kết thúc bằng cách thêm một cặp dấu ngoặc đơn ( ... )

def a = ("test"
  + "test"
  + "test")

Tùy chọn thứ hai là sử dụng dấu gạch chéo ngược \, ở cuối mỗi dòng:

def a = "test" \
  + "test" \
  + "test"

FWIW, điều này giống với cách hoạt động của các câu lệnh nhiều dòng trong Python.


Điều thứ hai cũng là cách VBA báo cáo multiline công việc: D (Chỉ với dấu gạch dưới thay vì gạch chéo ngược, vì VBA.)
Charles Gỗ

Tùy chọn thứ hai không thành công đối với tôi trong tệp Jenkins. Tùy chọn đầu tiên đã hoạt động.
SilverJan

Nitpick: Chuỗi nhiều dòng trong Python không yêu cầu toán tử nối khi sử dụng parens, vì vậy nó không hoàn toàn giống nhau.
Big McLargeHuge

17

Tương tự như stripMargin(), bạn cũng có thể sử dụng dảiIndent () như

def a = """\
        test
        test
        test""".stripIndent()

Bởi vì

Dòng có số khoảng trắng đầu tiên ít nhất sẽ xác định số cần loại bỏ.

bạn cũng cần phải thụt lề "test" đầu tiên và không đặt nó trực tiếp sau inital """( \đảm bảo chuỗi nhiều dòng không bắt đầu bằng một dòng mới).


2
cái gì vậy?
Joe Phillips

4
Tôi đã cải thiện câu cuối cùng của mình để giải thích nó tốt hơn.
sschuberth
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.