Bagaimana cara memecah baris kode yang panjang di Golang?


108

Berasal dari Python, saya tidak terbiasa melihat baris kode lebih dari 80 kolom. Jadi ketika saya menemukan ini:

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

Saya mencoba untuk memecahkannya

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

Tapi saya mengerti

 syntax error: unexpected \

Saya juga mencoba melanggar batas dengan menekan enter dan meletakkan titik koma di akhir:

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

Tapi saya kembali mendapatkan:

syntax error: unexpected .

Jadi saya bertanya-tanya apa cara golangic untuk melakukannya?

Jawaban:


122

Pertama beberapa latar belakang. Tata bahasa formal Go menggunakan titik koma ";"sebagai terminator dalam banyak produksi, tetapi program Go mungkin menghilangkan sebagian besar dari mereka (dan mereka harus memiliki sumber yang lebih jelas dan mudah dibaca; gofmtjuga menghapus titik koma yang tidak perlu).

Spesifikasi mencantumkan aturan yang tepat. Spec: Titik Koma:

Tata bahasa formal menggunakan titik koma ";" sebagai terminator dalam sejumlah produksi. Program Go mungkin menghilangkan sebagian besar titik koma ini menggunakan dua aturan berikut:

  1. Ketika input dipecah menjadi token, titik koma secara otomatis dimasukkan ke aliran token segera setelah token terakhir baris jika token itu

  2. Untuk memungkinkan pernyataan kompleks menempati satu baris, titik koma dapat dihilangkan sebelum penutup ")" atau "}".

Jadi seperti yang Anda lihat jika Anda memasukkan karakter baris baru setelah tanda kurung ), tanda titik koma ;akan disisipkan secara otomatis sehingga baris berikutnya tidak akan dianggap sebagai kelanjutan dari baris sebelumnya. Inilah yang terjadi dalam kasus Anda, dan baris berikutnya yang dimulai dengan .Scan(&ReadUser.ID,...akan memberi Anda kesalahan waktu kompilasi karena ini berdiri sendiri (tanpa baris sebelumnya) adalah kesalahan waktu kompilasi:syntax error: unexpected .

Jadi Anda dapat memutuskan baris Anda kapan saja yang tidak bertentangan dengan aturan yang tercantum di bawah poin di 1.atas.

Biasanya Anda dapat mematahkan garis setelah koma ,, setelah pembukaan kurung misalnya (, [, {, dan setelah sebuah titik .yang mungkin referensi bidang atau metode beberapa nilai. Anda juga dapat memutuskan baris Anda setelah operator biner (yang membutuhkan 2 operan), misalnya:

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

Satu hal yang perlu diperhatikan di sini adalah bahwa jika Anda memiliki struct atau slice atau peta literal yang mencantumkan nilai awal, dan Anda ingin memutus baris setelah mencantumkan nilai terakhir, Anda harus meletakkan koma wajib ,meskipun ini adalah nilai terakhir dan tidak lebih banyak akan mengikuti, misalnya:

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

Ini untuk menyesuaikan dengan aturan titik koma, dan juga agar Anda dapat mengatur ulang dan menambahkan baris baru tanpa harus berhati-hati dalam menambahkan / menghapus koma terakhir; misal, Anda cukup menukar 2 baris tanpa harus menghapus dan menambahkan koma baru:

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

Hal yang sama berlaku saat mencantumkan argumen ke pemanggilan fungsi:

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

3
Saya terus menempatkan koma di akhir literal javascript. #hatejs
Paulo Scardine

27
TL; DR: Biasanya Anda dapat memutuskan baris Anda setelah koma ,, setelah membuka tanda kurung misalnya (, [, {, dan setelah titik. Yang mungkin mereferensikan bidang atau metode dari beberapa nilai.
Peeter Kokk

2
Harus menambahkan koma ekstra di bagian akhir mengingatkan saya pada beberapa bug IE js lama, mengerikan
Christophe Roussy

4
@ChristopheRoussy Ini subjektif, saya untuk satu cinta bahwa semua baris harus diakhiri dengan koma, dan saya dapat mengatur ulang dan menambahkan baris baru dengan mudah tanpa harus berhati-hati dalam menambahkan / menghapus koma.
icza

@icza, saya juga suka mereka mengakhirinya dengan koma, tetapi tidak harus melakukannya untuk yang terakhir :)
Christophe Roussy

22

Cara termudah adalah dengan meninggalkan operator ( .) di baris pertama.

\ kelanjutan baris juga tidak disarankan di banyak panduan gaya python, Anda dapat membungkus seluruh ekspresi dalam tanda kurung jika Anda berpindah bolak-balik antara go dan python karena teknik ini berfungsi di kedua bahasa.


Tip bagus tentang meninggalkan operator di akhir. Berhasil.
Karlom

1
membungkus dalam tanda kurung tidak berlaku di go afaik. Pergi masih memasukkan titik koma dalam tanda kurung
Adrian Shum

Saya baru saja mencobanya, dan Go benar-benar menyisipkan titik koma yang tidak terlihat, bahkan di dalam tanda kurung. Jadi ini hanya berfungsi di Python, bukan di Go.
Roland Illig

@RolandIllig Ini pasti berhasil: play.golang.org/p/oFKaxLTphU
tobyodavies

Maaf atas kata-kata saya, saya mengacu pada penggunaan tanda kurung (tapi tidak menulisnya). Membungkus ekspresi dalam tanda kurung mungkin bisa digunakan di Python, tapi tidak bisa di Go.
Roland Illig

16

Ini masalah gaya, tapi saya suka:

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

16

Seperti yang disebutkan, ini adalah masalah preferensi gaya. Saya memahami bahwa pencipta Go telah menyarankan gaya berdasarkan pengalaman mereka yang saya pelajari, tetapi juga menyimpan beberapa gaya saya sendiri dari pengalaman saya.

Di bawah ini adalah bagaimana saya akan memformat ini:

err := database.
  QueryRow("select * from users where user_id=?", id).
  Scan(
    &ReadUser.ID,
    &ReadUser.Name,
    &ReadUser.First,
    &ReadUser.Last,
    &ReadUser.Email,
  )
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.