Halo semuanya!
Nama saya Lex dan saya adalah pembawa acara saluran 
YouTube " 
IT Beard ." Dan saya adalah rekan berusia 6 tahun. Baru-baru ini, saya memiliki keinginan untuk melampaui teknologi inti saya (C # /. NET), dan untuk memahami esensi dari 
paradoks Blob . Saya dengan tegas memutuskan bahwa saya akan mencoba sendiri dalam bahasa lain, dan pilihan secara kebetulan jatuh pada Go.
Untuk mendapatkan pengetahuan secara terstruktur, saya mendaftar untuk kursus dari mail.ru, yang dapat Anda temukan di sini: 
https://www.coursera.org/learn/golang-webservices-1 . Sebenarnya, apa yang saya pelajari dari minggu pertama pelatihan dalam kursus ini akan dibahas lebih lanjut. Ayo pergi!
Saya akan mulai dengan intro kecil pada bahasa. 
Go sudah dikembangkan pada saat prosesor multi-core (2007-2009), jadi semuanya sangat baik di sini dengan paralelisasi kerja lintas core. Selain itu, bahasa berfungsi dengan baik dengan permintaan kompetitif (simultan). Secara umum, pencarian untuk semua jenis layanan web dan sistem web yang dimuat. Hanya apa yang diperlukan untuk saya, karena saya telah mengembangkan api web (Web API) dalam beberapa tahun terakhir.
Mulai
Untuk bekerja dengan bahasa tersebut, cukup dengan menginstal 
paket perangkat lunak "Go tools" dengan ukuran 118mb, dan Anda dapat mulai mengkodekan.
Skrip memiliki 
ekstensi * .go dan dijalankan oleh perintah 
go pada baris perintah (Saya adalah penganut baris perintah windows). Perintah 
gofmt menempatkan semua ruang lekukan dan membuat permen dari file (kode beautifier di luar kotak). Seperti pada subnet favorit saya, di Go, eksekusi program dimulai dengan metode 
utama .
Fitur keren langsung menarik perhatian saya - 
Anda tidak bisa meletakkan tanda titik koma di akhir baris :)
Go adalah bahasa lain (bersama dengan python, c #, php, js, ts, dan lainnya), yang nyaman untuk digunakan dalam VSCode. 
VSCode sendiri memberikan semua paket dan dependensi yang diperlukan saat kode ditulis. Saat menyimpan IDE, silakan jalankan gofmt untuk Anda dan buat kodenya lebih indah.
Variabel
Semuanya akrab di sini: ada banyak jenis berbeda, ada nilai default. Dari luar biasa untuk donor, kata kunci 
var berarti bahwa variabel akan melangkah lebih jauh, dan jenis variabel dapat dideklarasikan atau belum setelah nama variabel. Tidak seperti biasanya.
Secara umum, ada banyak cara untuk mendeklarasikan dan menginisialisasi variabel. Anda bahkan dapat menetapkan nilai ke beberapa variabel, dipisahkan dengan koma, pada baris yang sama. Dan omong-omong, tidak ada gips implisit.
Dan Go juga memiliki operator " 
: = ", yang memungkinkan Anda untuk mendeklarasikan dan segera menginisialisasi variabel baru (dan hampir selalu hanya baru). Hai Pascal;)
Rekam tampilan:
perem1, perem2 := 2, 3 
baik membuat dua variabel baru, atau membuat salah satunya, dan yang kedua hanya memberikan nilai baru. Ini untuk mengatakan bahwa jika kedua variabel sudah ada, maka ini tidak akan berfungsi dan Anda akan mendapatkan kesalahan, mereka mengatakan menggunakan tugas yang biasa. Operator 
: = harus membuat sesuatu :)
Ada juga palsu lucu - karakter garis bawah "_". Itu berarti tidak adanya variabel, sesuatu seperti itu :) 
(di benda tajam, ternyata, itu juga adalah: https://docs.microsoft.com/en-us/dotnet/csharp/discards )
Momen menyenangkan dengan string: jumlah standar dari panjang string dari string 
len (str) menghitung 
byte , dan dalam UTF8 karakter dapat memiliki bobot lebih. Untuk menghitung karakter yang disebut 
rune , Anda perlu menggunakan metode 
utf8.RuneCountInString (str) dari paket "utf8". Dan, namun - kami tidak mengubah garis (seperti di favorit Anda).
Konstanta
Konstanta dapat dideklarasikan dalam batch. Konstanta memiliki tipe yang menarik, atau sesuatu - 
iota . Saya akan menyebutnya Jopta. Jopta memungkinkan Anda untuk melakukan beberapa konstanta berdasarkan yang lain, sesuatu seperti iterator untuk konstanta (sesuatu yang mengingatkan 
hasil dari sebuah subnet).
Namun, konstanta mungkin tidak diketik. Untuk konstanta seperti itu, kompiler memutuskan jenisnya pada waktu yang tepat. Mudahnya, apa yang sudah ada.

Pointer
Ya, ya! Ada petunjuk di sini, tapi sepertinya tidak terlalu menakutkan. Mereka mengatakan bahwa mereka tidak bernomor, dan Anda tidak bisa mendapatkan pointer berikutnya dengan menambahkan genap ke pointer. Ini dia semacam variabel yang menyimpan tautan ke variabel lain (sejauh ini saya memahaminya).
Pointer ditentukan melalui ampersant atau metode 
(tipe) baru (untuk mendapatkan pointer ke tipe, bukan variabel):

Jika Anda mengakses pointer secara langsung, tautannya akan berubah. Dan jika melalui operator " 
* ", maka nilai variabel yang terletak di belakang pointer (yang ditunjukkannya) berubah. Secara umum, belum terlalu jelas, tetapi kemudian, kata mereka, itu akan menjadi lebih jelas.
Array
Ukuran array adalah bagian dari tipe data! Jadi, array dimensi yang berbeda sebenarnya adalah tipe data yang berbeda dan tidak kompatibel.

Tapi untuk apa array diperlukan jika mereka begitu kering dan tidak dapat diubah (mereka tidak dapat diubah dalam runtime). Oleh karena itu, kami membuat 
irisan (irisan) berdasarkan array.

Sepotong memiliki 
panjang dan 
kapasitas . Itu mengingatkan saya sedikit tipe data 
nvarchar dari SQL. Yaitu Anda dapat mengalokasikan ruang memori (alokasi memori) untuk array Anda, tetapi meletakkan array berapa pun di sana (hingga kapasitas). Singkatnya, masalahnya menarik, Anda harus terbiasa. Untuk penggunaan irisan yang nyaman, ada segala macam metode seperti 
make (), append (), len (), cap (), dan, yang pasti, yang lain. Dari satu irisan (irisan), Anda dapat sedikit mendapatkan sub iris (irisan irisan). Dan omong-omong, 
append () memperluas kapasitas slice.
Jika sub-irisan sama dengan irisan, maka sebenarnya mereka akan merujuk pada satu bagian memori. Dan karenanya, perubahan nilai dalam satu irisan akan menyebabkan perubahan pada irisan kedua. Tetapi jika salah satunya diperluas melalui 
append () , sepotong memori baru akan dialokasikan.
Singkatnya, semuanya serius dengan memori :)
Peta, tabel hash, array asosiatif
Semua ini satu dan sama. Go hash tables untuk pencarian tombol cepat. Diinisialisasi sebagai berikut:

Anda dapat membuat subtabel (Peta Peta), dll. (tingkat bersarang, semacam suka) Ada nilai default yang kembali pada kunci yang tidak ada. Ini diambil dari jenis kunci (untuk bool, lalu false). Untuk mengetahui apakah suatu variabel telah kembali secara default, mis. bahwa kunci tidak ada - gunakan kunci untuk keberadaan kunci (hal yang menarik):

Struktur kontrol
Ada hal lain. Sedikit lebih menarik daripada di benda tajam, karena Anda dapat menggunakan kondisi inisialisasi jika.
Ada kasus swith. Istirahat tidak perlu diatur, dan ini perbedaan. Inversi logika) Jika Anda ingin kondisi berikut diperiksa juga, Anda harus menulis 
fallthrough .
Ada untuk. Dan semua dengan siklus.

Dengan irisan berulang lebih menyenangkan (operator jangkauan):

Dan bahkan dengan peta hash Anda dapat beralih (meskipun urutannya akan sering berbeda, karena peta tidak terarah):

Untuk jenis 
rentang string iterates on rune, bukan bytes.
Fungsi
Dinyatakan melalui kata kunci 
func . Selain itu, inversi logika sekali lagi dibandingkan dengan subnet - parameter input ditunjukkan terlebih dahulu, dan kemudian jenis nilai pengembalian (Anda dapat langsung menamainya).
Fungsi dapat mengembalikan 
beberapa hasil , seperti halnya 
tupel di subnet .
Nilai bernama yang dikembalikan fungsi diinisialisasi secara default dengan nilai default untuk jenis.
Namun, Anda dapat membuat 
fungsi variabel yang memiliki jumlah tak terbatas parameter input dari jenis yang sama (seperti param di subnet). Dan kemudian jenis irisan tertentu datang ke input fungsi.
Fungsi mungkin memiliki nama, atau mungkin tanpa nama - 
anonim . Dan mereka dapat dipanggil, dapat ditugaskan ke variabel. Sepertinya JavaScript. Anda bahkan dapat membuat tipe berdasarkan fungsi! Fungsi dapat diteruskan sebagai parameter (baca delegasi dari subnet)
Bahkan ada 
penutupan (uuuh, menakutkan)! Anda dapat menjangkau variabel dari fungsi di luarnya (baca, dalam fungsi induk). Ini adalah pai.
Anda dapat mendeklarasikan 
eksekusi fungsi yang ditangguhkan . Melalui kata kunci 
penundaan ini dilakukan. Yaitu fungsi yang ditangguhkan dieksekusi pada akhir fungsi di mana mereka dinyatakan, dalam urutan terbalik dari deklarasi fungsi yang ditangguhkan ini. Di sini Selain itu, inisialisasi argumen fungsi tertunda terjadi ketika blok 
defer dideklarasikan . Ini penting, terutama jika fungsi lain diambil sebagai argumen - itu akan dieksekusi jauh lebih awal dari yang Anda harapkan!
PANIC! Go memiliki fungsi seperti itu - 
panik () . Ini seperti 
melempar , tetapi lebih buruk. Fungsi ini menghentikan eksekusi program. Tapi kepanikan yang sama ini dapat diproses oleh penundaan, karena dijalankan dengan cara apa pun di akhir fungsi, bahkan setelah panik. Namun - panik, ini bukan try-catch. Ini lebih buruk!
Struktur (objek dekat)
Go dikatakan bukan bahasa paradigma OOP. Tetapi ada hal-hal seperti 
struktur . Jika Anda berasal dari dunia subnetting, maka Anda tahu bahwa kami juga memiliki struktur - ini adalah pemetaan objek yang dapat disimpan di tumpukan (tipe nilai). Dalam Go, struktur adalah satu-satunya cara untuk melakukan sesuatu seperti objek. Saya belum dapat berbicara tentang jenis-jenis nilai, tetapi sifat interaksi dengan struktur sangat mirip dengan yang terperinci.
Setiap struktur pada dasarnya adalah tipe yang terpisah dan dapat memiliki satu set properti tipe tertentu (termasuk tipe struktur lain atau tipe fungsi):

Selain itu, mekanisme tertentu pewarisan objek langsung dari subnet terlihat di sini. Pada gambar di atas, struktur 
akun bersarang dengan struktur 
Orang . Ini berarti bahwa semua bidang dari 
Orang akan tersedia dalam variabel jenis 
Akun . Jika nama properti bertepatan (dalam contoh 
Id di atas 
, Nama ), tidak akan ada konflik, tetapi nilai bidang yang lebih tinggi akan diambil:

Metode
Ya, tidak hanya kesamaan objek, tetapi juga metode. Hampir OOP :) Suatu metode adalah 
fungsi yang terikat ke tipe tertentu (misalnya, ke struktur). Metode berbeda dari fungsi dalam deklarasi: setelah kata kunci 
func , dalam tanda kurung Anda perlu menentukan jenis yang dimiliki metode ini dan peran meneruskan variabel jenis ini. Apa perannya Jika Anda meletakkan tanda bintang di depan jenis, maka variabel akan dilewatkan oleh referensi (ingat pointer, itu ada di sana juga), dan sebagai hasilnya, di dalam metode kami akan bekerja dengan jenis tertentu, bukan salinannya.

Dari gambar di atas, kita dapat menyimpulkan bahwa 
UpdateName tidak masuk akal, karena itu mengubah salinan struktur, dan bukan yang asli. Dan salinan ini tidak kembali. Sementara 
SetName akan mengubah struktur asli (terima kasih kepada tanda bintang dan lewat referensi).
Metode dalam struktur 
diwariskan (dan menurut aturan pewarisan properti), yaitu struktur induk memiliki akses ke semua metode yang bersarang dalam strukturnya.
Jenis lain dapat memiliki metode, bukan hanya struktur. Ini mungkin tampak seperti metode ekstensi dari subnet, tetapi tidak. Metode di Go hanya dapat dibuat untuk tipe lokal, mis. jenis yang dideklarasikan dalam paket ini (tentang paket sedikit lebih jauh).
Paket, Cakupan, Ruang nama
Baru saja saya menyadari bahwa Go tidak memiliki NEIMSPACE! Umumnya! Saya menyadari ini ketika, setelah kompilasi, kesalahan keluar, mereka berkata dalam satu folder saya memiliki dua file dengan metode utama. Ternyata pada tahap kompilasi segala sesuatu mulai dari ayah tampaknya direkatkan dalam satu kanvas! Folder sebenarnya adalah namespace. Itu keajaiban seperti itu, kawan-kawan :)
Omong-omong, inilah yang dikatakan dermaga:

Catatan untuk diri sendiri: 
merokok dermagaDan inilah artikel kecil lain dalam topik ini: 
https://www.callicoder.com/golang-packages/#the-main-package-and-main-functionJadi, kata mereka, struktur folder dasar terlihat seperti:

bin - binari terkompilasi
pkg - file objek sementara
src - sources
Paket merujuk ke nama folder tempat file paket berada. Ya, satu paket dapat memiliki banyak file yang saling diimpor.
Aturan lain yang menarik: fungsi, properti, variabel dan konstanta dimulai dengan huruf kapital 
dapat digunakan di luar paket , yaitu 
diimpor . Semuanya dengan huruf kecil hanya digunakan di dalam paket. Analog 
pengubah akses dari subnet.
Kata kunci 
impor berfungsi dalam file, bukan paket.
Antarmuka
Antarmuka di sini menarik. Kita tidak perlu mewarisi antarmuka dari struktur kita. Cukup bahwa struktur, yang datang sebagai parameter input ke metode tertentu yang mengambil tipe antarmuka, mengimplementasikan metode antarmuka ini. Dan tidak ada masalah. Yaitu metode antarmuka tidak perlu diimplementasikan oleh struktur. Tetapi struktur harus berisi implementasi dari semua metode yang diperlukan dalam fungsi tertentu, di mana tipe antarmuka digunakan sebagai parameter input.
Ternyata, berbeda dengan, di Go, antarmuka adalah karakteristik fungsi yang digunakannya, dan bukan karakteristik struktur tertentu (objek).
Jika lebih sederhana, maka logikanya adalah ini: Anda tidak perlu bisa menjadi dukun. Jika Anda tahu bagaimana cara dukun, maka kemungkinan besar Anda adalah bebek :)
Dan omong-omong, jika struktur Anda mengimplementasikan semua metode beberapa antarmuka, maka struktur ini 
dapat ditetapkan sebagai nilai-nilai variabel dari antarmuka yang diimplementasikan . Sesuatu seperti itu :)
Ketik sakelar sakelar
Go memiliki switch-case khusus yang dapat bekerja tergantung pada tipe yang masuk. Hal yang keren:

Ngomong-ngomong, ini adalah bagaimana Anda dapat 
mengubah satu jenis ke yang lain (misalnya, jenis antarmuka menjadi jenis struktur untuk mendapatkan bidang struktur yang tidak dapat diakses dari antarmuka):
 ok
ok - tanda Boolean bahwa konversi berhasil. Kami sudah menemukan tanda-tanda :)
Antarmuka kosong adalah binatang buas di dunia Go. Itu bisa mengambil tipe apa saja. Sesuatu seperti 
dinamis atau 
Objek dalam. Misalnya, digunakan di 
fmt.Println () dan fungsi serupa yang menggunakan antarmuka kosong dalam implementasi.
Antarmuka dapat dibangun menjadi satu sama lain, dan dengan demikian membuat komposisi antarmuka (apa yang dikatakan dalam huruf 
I (antarmuka pemisahan) dari prinsip-prinsip 
SOLID )
Tes
Di Go, semua fungsi tes dimulai dengan kata 
Test , dan input dari modul 
pengujian pengujian diterima. File diberi nama dengan nama file tes + kata _test ( 
main_test.go - tes untuk file 
main.go ). Selain itu, baik file tes dan file dalam satu paket!

Epilog
Itu saja! Terima kasih atas perhatian Anda, dan saya siap untuk membahas masalah dalam komentar. Saya akan menemui Anda di catatan berikut dari kelas saya!
PS Anda dapat melihat semua kode saya berjalan pada minggu ini pelatihan di 
github