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 - 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