Apa yang salah dengan String multi-baris Groovy?

105

Skrip Groovy menimbulkan kesalahan:

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

Kesalahan:

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

Meskipun skrip ini berfungsi dengan baik:

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

Mengapa?

yegor256
sumber
5
Jika itu membantu orang lain, Anda bisa mendapatkan kesalahan yang sama dengan kode like def a = b + + "/" + c. Dalam hal ini, dua simbol + jelas merupakan masalahnya.
Geoff Hackworth

Jawaban:

236

Karena groovy tidak memiliki penanda EOL (seperti ;), akan membingungkan jika Anda meletakkan operator di baris berikut

Ini akan bekerja sebagai gantinya:

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

seperti yang diketahui pengurai Groovy untuk mengharapkan sesuatu di baris berikut

Groovy melihat dokumen asli Anda defsebagai tiga pernyataan terpisah. The wakilnya pertama testuntuk a, kedua dua mencoba untuk membuat "test"positif (dan ini adalah di mana ia gagal)

Dengan new Stringmetode konstruktor, pengurai Groovy masih dalam konstruktor (karena kurung kurawal belum ditutup), sehingga secara logis dapat menggabungkan tiga baris menjadi satu pernyataan

Untuk String multi-baris yang sebenarnya, Anda juga dapat menggunakan kutipan tiga:

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

Akan membuat String dengan tes pada tiga baris

Selain itu, Anda bisa membuatnya lebih rapi dengan:

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

yang stripMarginmetode akan memangkas kiri (sampai dengan dan termasuk |char) dari setiap baris

tim_yates
sumber
6
Atau cukup gunakan stripIndent () sebagai ganti stripMargin().
sschuberth
Ya, dan hilangkan |karakter di baris tambahan
tim_yates
4
Anda dapat menggunakan tanda kutip ganda di dalam """string
tim_yates
3
Benar, saya telah mengedit jawabannya untuk menunjukkan bagaimana Anda perlu sedikit memformat ulang kode agar stripIndent()berfungsi.
sschuberth
2
Karena a) Saya sudah mempostingnya sebagai komentar, dan b) tidak jauh berbeda dengan jawaban ini.
sschuberth
18

Mirip dengan stripMargin(), Anda juga bisa menggunakan stripIndent () seperti

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

Karena

Baris dengan jumlah spasi terdepan paling sedikit menentukan jumlah yang akan dihapus.

Anda juga perlu mengindentasi "test" pertama dan tidak langsung meletakkannya setelah inital """( \memastikan string multi-baris tidak dimulai dengan baris baru).

sschuberth.dll
sumber
2
apa \ untuk?
Joe Phillips
4
Saya telah memperbaiki kalimat terakhir saya untuk menjelaskannya dengan lebih baik.
sschuberth
17

Anda dapat memberi tahu Groovy bahwa pernyataan tersebut harus mengevaluasi setelah baris berakhir dengan menambahkan sepasang tanda kurung ( ... )

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

Opsi kedua adalah menggunakan garis miring terbalik \,, di akhir setiap baris:

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

FWIW, ini identik dengan cara kerja pernyataan multi-baris Python.

cmcginty.dll
sumber
Yang kedua juga bagaimana pernyataan multiline VBA bekerja: D (Hanya dengan garis bawah dan bukan garis miring terbalik, karena VBA.)
Charles Wood
Opsi kedua gagal bagi saya di Jenkinsfile. Opsi pertama berhasil.
SilverJan
Nitpick: String multi-baris Python tidak memerlukan operator penggabungan saat menggunakan tanda kurung, jadi tidak persis sama.
Big McLargeHuge