Dokumen pengantar mendedikasikan banyak paragraf untuk menjelaskan perbedaan di antara keduanya new()
danmake()
, tetapi dalam praktiknya, Anda dapat membuat objek dalam cakupan lokal dan mengembalikannya.
Mengapa Anda menggunakan pasangan pengalokasi?
m := map[string]int{}
sebaliknyam := make(map[string]int)
? tidak perlu mengalokasikan ukuran juga.Go memiliki banyak cara alokasi memori dan inisialisasi nilai:
&T{...}
,&someLocalVar
,new
,make
Alokasi juga dapat terjadi saat membuat literal komposit.
new
dapat digunakan untuk mengalokasikan nilai-nilai seperti bilangan bulat,&int
ilegal:Perbedaan antara
new
danmake
dapat dilihat dengan melihat contoh berikut:Misalkan Go tidak memiliki
new
danmake
, tetapi memiliki fungsi bawaanNEW
. Maka kode contoh akan terlihat seperti ini:Itu
*
wajib , jadi:Ya, menggabungkan
new
danmake
menjadi satu fungsi bawaan dimungkinkan. Namun, ada kemungkinan bahwa fungsi built-in tunggal akan menyebabkan lebih banyak kebingungan di antara programmer Go daripada memiliki dua fungsi built-in.Mempertimbangkan semua poin di atas, tampaknya lebih tepat untuk
new
danmake
tetap terpisah.sumber
int
dibuat.make(Point)
danmake(int)
dalam 2 baris terakhir?make
fungsi mengalokasikan dan menginisialisasi objek dengan tipe slice, map, atau chan only. Sepertinew
, argumen pertama adalah tipe. Tapi, bisa juga argumen kedua, ukuran. Tidak seperti yang baru, tipe return make sama dengan tipe argumennya, bukan pointer. Dan nilai yang dialokasikan diinisialisasi (tidak diatur ke nilai nol seperti yang baru). Alasannya adalah bahwa slice, map dan chan adalah struktur data. Mereka perlu diinisialisasi, kalau tidak mereka tidak akan dapat digunakan. Inilah alasan baru () dan make () harus berbeda.Contoh-contoh berikut dari Effective Go membuatnya sangat jelas:
sumber
new([]int)
, itu hanya mengalokasikan memori untuk [] int, tetapi tidak menginisialisasi sehingga hanya mengembalikannil
; bukan penunjuk ke memori karena tidak dapat digunakan.make([]int)
mengalokasikan dan menginisialisasi sehingga dapat digunakan, lalu kembalikan alamatnya.new(T)
- Mengalokasikan memori, dan menetapkannya ke nilai nol untuk jenis T ....that adalah
0
untuk int ,""
untuk tali dannil
untuk jenis direferensikan ( slice , peta , chan )Perhatikan bahwa tipe yang direferensikan hanyalah pointer ke beberapa struktur data yang mendasarinya , yang tidak akan dibuat oleh
new(T)
Contoh: dalam kasus slice , array yang mendasarinya tidak akan dibuat, sehingga
new([]int)
mengembalikan pointer ke nol.make(T)
- memori Alokasikan untuk jenis direferensikan data ( slice , peta , chan ), ditambah menginisialisasi mereka struktur data yang mendasariContoh: dalam kasus slice , array yang mendasarinya akan dibuat dengan panjang dan kapasitas yang ditentukan.
Ingatlah, tidak seperti C, array adalah tipe primitif di Go!
Yang telah dibilang:
make(T)
berperilaku seperti sintaks komposit-literalnew(T)
berperilaku sepertivar
(ketika variabel tidak diinisialisasi)Jalankan programnya
Bacaan lebih lanjut:
https://golang.org/doc/effective_go.html#allocation_new https://golang.org/doc/effective_go.html#allocation_make
sumber
Anda perlu
make()
membuat saluran dan peta (dan irisan, tetapi itu juga dapat dibuat dari array). Tidak ada cara alternatif untuk membuatnya, jadi Anda tidak bisa menghapusnyamake()
dari leksikon Anda.Adapun
new()
, saya tidak tahu alasan apa pun begitu saja mengapa Anda membutuhkannya ketika Anda dapat menggunakan sintaks struct. Itu memang memiliki makna semantik yang unik, yaitu "membuat dan mengembalikan struct dengan semua bidang diinisialisasi ke nilai nol", yang dapat berguna.sumber
Terlepas dari semua yang dijelaskan dalam Efektif Go , Perbedaan utama antara
new(T)
dan&T{}
adalah bahwa yang terakhir secara eksplisit melakukan alokasi tumpukan. Namun perlu dicatat bahwa ini tergantung pada implementasi dan karenanya dapat berubah.Dibandingkan
make
dengannew
sedikit masuk akal karena keduanya melakukan fungsi yang sama sekali berbeda. Tetapi ini dijelaskan secara rinci dalam artikel yang ditautkan.sumber
&T{}
secara eksplisit melakukan alokasi tumpukan adalah AFAIK tidak didasarkan pada apa pun dalam spesifikasi. Sebenarnya saya percaya analisis melarikan diri sudah menyimpan * T pada stack bila memungkinkan dengan cara yang sama persis dengannew(T)
.new (T): mengembalikan pointer ke tipe T nilai tipe * T, mengalokasikan dan nol memori. baru (T) setara dengan & T {} .
make (T): mengembalikan nilai yang diinisialisasi dari tipe T , Ini mengalokasikan dan menginisialisasi memori. Ini digunakan untuk irisan, peta dan saluran.
sumber