เกิดอะไรขึ้นกับ Groovy multi-line String?


106

สคริปต์ Groovy ทำให้เกิดข้อผิดพลาด:

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

ข้อผิดพลาด:

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

แม้ว่าสคริปต์นี้จะทำงานได้ดี:

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

ทำไม?


5
def a = b + + "/" + cในกรณีที่จะช่วยให้คนอื่นคุณจะได้รับข้อผิดพลาดเดียวกันด้วยรหัสเช่น ในกรณีนี้เห็นได้ชัดว่าสัญลักษณ์ + สองตัวเป็นปัญหา
Geoff Hackworth

คำตอบ:


237

เนื่องจาก groovy ไม่มีเครื่องหมาย EOL (เช่น ; ) จึงสับสนหากคุณใส่ตัวดำเนินการในบรรทัดต่อไปนี้

สิ่งนี้จะใช้งานได้แทน:

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

เนื่องจากตัวแยกวิเคราะห์ Groovy รู้ว่าจะคาดหวังบางสิ่งในบรรทัดต่อไปนี้

Groovy มองว่าต้นฉบับของคุณdefเป็นสามประโยคแยกกัน คนแรกมอบหมายtestให้aสองคนที่สองพยายามทำให้"test"เป็นบวก (และนี่คือจุดที่ล้มเหลว)

ด้วยnew Stringวิธีการสร้างตัวแยกวิเคราะห์ Groovy ยังคงอยู่ในตัวสร้าง (เนื่องจากวงเล็บปีกกายังไม่ปิด) ดังนั้นจึงสามารถรวมสามบรรทัดเข้าด้วยกันเป็นคำสั่งเดียวอย่างมีเหตุผล

สำหรับสตริงหลายบรรทัดที่แท้จริงคุณยังสามารถใช้เครื่องหมายคำพูดสามบรรทัด:

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

จะสร้างสตริงที่มีการทดสอบสามบรรทัด

นอกจากนี้คุณสามารถทำให้มันดูดีขึ้นได้โดย:

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

stripMarginวิธีการจะตัดซ้าย (และรวมทั้ง|ถ่าน) จากแต่ละบรรทัด


6
หรือใช้stripIndent ()แทนstripMargin().
sschuberth

ใช่และละเว้น|อักขระในบรรทัดพิเศษ
tim_yates

4
คุณสามารถใช้เครื่องหมายคำพูดคู่ใน"""สตริง
tim_yates

3
ถูกต้องฉันได้แก้ไขคำตอบเพื่อแสดงว่าคุณจะต้องฟอร์แมตโค้ดใหม่เล็กน้อยเพื่อให้stripIndent()ทำงานได้อย่างไร
sschuberth

2
เพราะ a) ฉันได้โพสต์ไว้เป็นความคิดเห็นแล้วและ b) มันก็ไม่ต่างจากคำตอบนี้มากนัก
sschuberth

18

เช่นเดียวกับstripMargin()คุณสามารถใช้stripIndent ()เช่น

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

เพราะว่า

บรรทัดที่มีช่องว่างนำหน้าน้อยที่สุดกำหนดจำนวนที่จะลบ

คุณต้องเยื้อง "การทดสอบ" แรกและอย่าใส่ไว้หลังอินอิทอลโดยตรง"""( \เพื่อให้แน่ใจว่าสตริงหลายบรรทัดไม่ได้ขึ้นต้นด้วยการขึ้นบรรทัดใหม่)


2
\ สำหรับอะไร?
Joe Phillips

4
ฉันปรับปรุงประโยคสุดท้ายให้อธิบายได้ดีขึ้น
sschuberth

17

คุณสามารถบอก Groovy ได้ว่าคำสั่งควรประเมินผ่านการสิ้นสุดบรรทัดโดยการเพิ่มวงเล็บคู่หนึ่ง ( ... )

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

ตัวเลือกที่สองคือการใช้แบ็กสแลช\ในตอนท้ายของแต่ละบรรทัด:

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

FWIW นี่เหมือนกับวิธีการทำงานของคำสั่งหลายบรรทัดของ Python


อันที่สองคือวิธีการทำงานของคำสั่งหลายบรรทัดของ VBA: D (เฉพาะที่มีเครื่องหมายขีดล่างแทนแบ็กสแลชเพราะ VBA)
Charles Wood

ตัวเลือกที่สองล้มเหลวสำหรับฉันใน Jenkinsfile ตัวเลือกแรกใช้งานได้
SilverJan

Nitpick: สตริงหลายบรรทัดของ Python ไม่ต้องการตัวดำเนินการต่อเมื่อใช้ parens ดังนั้นจึงไม่เหมือนกันทุกประการ
Big McLargeHuge
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.