Làm thế nào để phá vỡ một dòng mã dài trong Golang?


107

Đến từ Python, tôi không quen nhìn các dòng mã dài hơn 80 cột. Vì vậy, khi tôi gặp phải điều này:

err := database.QueryRow("select * from users where user_id=?", id).Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email)

Tôi đã cố gắng phá vỡ nó để

err := database.QueryRow("select * from users where user_id=?", id) \
    .Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email)

Nhưng tôi nhận được

 syntax error: unexpected \

Tôi cũng đã thử ngắt dòng bằng cách nhấn enter và đặt dấu chấm phẩy ở cuối:

err := database.QueryRow("select * from users where user_id=?", id) 
.Scan(&ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email);

Nhưng tôi lại nhận được:

syntax error: unexpected .

Vì vậy, tôi tự hỏi cách golangic để làm như vậy là gì?

Câu trả lời:


121

Đầu tiên một số nền tảng. Ngữ pháp chính thức của cờ vây sử dụng dấu chấm phẩy ";"làm dấu chấm dứt trong nhiều sản phẩm, nhưng các chương trình cờ vây có thể bỏ qua hầu hết chúng (và chúng phải có nguồn rõ ràng, dễ đọc; gofmtcũng loại bỏ dấu chấm phẩy không cần thiết).

Đặc điểm kỹ thuật liệt kê các quy tắc chính xác. Spec: Dấu chấm phẩy:

Ngữ pháp chính thức sử dụng dấu chấm phẩy ";" như những kẻ hủy diệt trong một số tác phẩm. Các chương trình Go có thể bỏ qua hầu hết các dấu chấm phẩy này bằng cách sử dụng hai quy tắc sau:

  1. Khi đầu vào được chia thành các mã thông báo, dấu chấm phẩy tự động được chèn vào dòng mã thông báo ngay sau mã thông báo cuối cùng của dòng nếu mã đó là

  2. Để cho phép các câu lệnh phức tạp chiếm một dòng, có thể bỏ qua dấu chấm phẩy trước dấu đóng ")" hoặc "}".

Vì vậy, như bạn có thể thấy nếu bạn chèn một ký tự dòng mới sau dấu ngoặc đơn ), dấu chấm phẩy ;sẽ được chèn tự động và do đó dòng tiếp theo sẽ không được coi là phần tiếp theo của dòng trước đó. Đây là những gì đã xảy ra trong trường hợp của bạn và vì vậy dòng tiếp theo bắt đầu bằng .Scan(&ReadUser.ID,...sẽ cung cấp cho bạn lỗi thời gian biên dịch vì lỗi này đứng riêng (không có dòng trước) là lỗi thời gian biên dịch:syntax error: unexpected .

Vì vậy, bạn có thể ngắt dòng của mình tại bất kỳ điểm nào không mâu thuẫn với các quy tắc được liệt kê ở điểm 1.trên.

Thông thường bạn có thể phá vỡ đường dây của bạn sau dấu phẩy ,, sau khi mở ngoặc ví dụ như (, [, {, và sau một chấm .có thể được tham khảo một lĩnh vực hoặc các phương pháp của một số giá trị. Bạn cũng có thể ngắt dòng của mình sau các toán tử nhị phân (những toán tử yêu cầu 2 toán hạng), ví dụ:

i := 1 +
        2
fmt.Println(i) // Prints 3

Một điều đáng lưu ý ở đây là nếu bạn có cấu trúc hoặc lát cắt hoặc bản đồ nghĩa đen liệt kê các giá trị ban đầu và bạn muốn ngắt dòng sau khi liệt kê giá trị cuối cùng, bạn phải đặt dấu phẩy bắt buộc ,mặc dù đây là giá trị cuối cùng và không nhiều hơn sẽ theo sau, ví dụ:

s := []int {
    1, 2, 3,
    4, 5, 6,  // Note it ends with a comma
}

Điều này tuân theo quy tắc dấu chấm phẩy và cũng để bạn có thể sắp xếp lại và thêm các dòng mới mà không cần phải quan tâm đến việc thêm / xóa dấu phẩy cuối cùng; Ví dụ: bạn có thể chỉ cần hoán đổi 2 dòng mà không phải xóa và thêm dấu phẩy mới:

s := []int {
    4, 5, 6,
    1, 2, 3,
}

Điều tương tự cũng áp dụng khi liệt kê các đối số cho một lệnh gọi hàm:

fmt.Println("first",
    "second",
    "third",       // Note it ends with a comma
)

3
Tôi tiếp tục đặt dấu phẩy ở cuối các ký tự javascript. #hatejs
Paulo Scardine

26
TL; DR: Thông thường bạn có thể phá vỡ đường dây của bạn sau dấu phẩy ,, sau khi mở ngoặc ví dụ (, [, {, và sau một chấm có thể được tham khảo một lĩnh vực hoặc các phương pháp của một số giá trị..
Peeter Kokk

2
Phải thêm một dấu phẩy ở cuối cùng nhắc nhở tôi về một số IE js lỗi cũ, khủng khiếp
Christophe Roussy

4
@ChristopheRoussy Thật chủ quan, tôi vì một tình yêu mà tất cả các dòng phải kết thúc bằng dấu phẩy, và tôi có thể sắp xếp lại và thêm các dòng mới một cách dễ dàng mà không cần phải thêm / bớt dấu phẩy.
icza

@icza, tôi cũng như họ kết thúc bằng một dấu phẩy, nhưng không cần phải làm điều đó cho người cuối cùng :)
Christophe Roussy

22

Cách đơn giản nhất là chỉ cần để toán tử ( .) trên dòng đầu tiên.

\ Tính liên tục của dòng cũng không được khuyến khích trong nhiều hướng dẫn kiểu python, bạn có thể gói toàn bộ biểu thức trong parens nếu bạn đang di chuyển qua lại giữa go và python vì kỹ thuật này hoạt động ở cả hai ngôn ngữ.


Mẹo hay về việc rời khỏi nhà điều hành ở cuối. Nó đã làm việc.
Karlom

1
gói trong dấu ngoặc đơn không hoạt động trong go afaik. Tiếp tục chèn dấu chấm phẩy trong dấu ngoặc đơn
Adrian Shum

Tôi vừa thử nó và Go thực sự chèn một dấu chấm phẩy vô hình, ngay cả bên trong dấu ngoặc đơn. Vì vậy, điều này chỉ hoạt động trong Python, không hoạt động trong Go.
Roland Illig

@RolandIllig Điều này chắc chắn hoạt động: play.golang.org/p/oFKaxLTphU
tobyodavies

Xin lỗi vì cách diễn đạt của tôi, tôi đã đề cập đến việc sử dụng dấu ngoặc đơn (nhưng không viết như vậy). Gói biểu thức trong dấu ngoặc đơn có thể hoạt động trong Python, nhưng không hoạt động trong Go.
Roland Illig,

16

Đó là vấn đề về phong cách, nhưng tôi thích:

err := database.QueryRow(
    "select * from users where user_id=?", id,
).Scan(
    &ReadUser.ID, &ReadUser.Name, &ReadUser.First, &ReadUser.Last, &ReadUser.Email,
)

16

Như đã đề cập, đây là vấn đề về sở thích phong cách. Tôi hiểu rằng những người sáng tạo cờ vây đã đề xuất một phong cách dựa trên kinh nghiệm của họ mà tôi học được từ đó nhưng cũng giữ một số phong cách riêng từ kinh nghiệm của tôi.

Dưới đây là cách tôi định dạng nó:

err := database.
  QueryRow("select * from users where user_id=?", id).
  Scan(
    &ReadUser.ID,
    &ReadUser.Name,
    &ReadUser.First,
    &ReadUser.Last,
    &ReadUser.Email,
  )
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.