Zadałem to pytanie kilka miesięcy temu, kiedy po raz pierwszy zacząłem badać Go. Od tamtej pory codziennie czytam o Go i programowaniu w Go.
Ponieważ nie otrzymałem jednoznacznej odpowiedzi na to pytanie (chociaż przyjąłem jedną odpowiedź), teraz odpowiem na nie sam, opierając się na tym, czego się nauczyłem, odkąd je zadałem:
Czy istnieje sposób na utworzenie tablicy / wycinka w Go bez zakodowanego na stałe rozmiaru tablicy?
Tak. Plasterki nie wymagają zakodowanej na stałe tablicy slice
od:
var sl []int = make([]int,len,cap)
Ten kawałek przydziela kod sl
, wielkości len
o wydajności cap
- len
i cap
to zmienne, które można przypisać w czasie wykonywania.
Dlaczego jest list.List
ignorowany?
Wydaje się, że główne powody, list.List
na które zwraca się niewielką uwagę w Go, to:
Jak wyjaśniono w odpowiedzi @Nick Craig-Wood, praktycznie nic nie można zrobić z listami, których nie można zrobić z plasterkami, często bardziej wydajnie iz czystszą, bardziej elegancką składnią. Na przykład konstrukcja zakresu:
for i:=range sl {
sl[i]=i
}
nie można używać z listą - wymagana jest pętla for w stylu C. W wielu przypadkach składnia w stylu kolekcji C ++ musi być używana z listami:
push_back
itp.
Co ważniejsze, list.List
nie jest silnie typowany - jest bardzo podobny do list i słowników Pythona, które pozwalają na mieszanie różnych typów w kolekcji. Wydaje się, że jest to sprzeczne z podejściem Go do rzeczy. Go jest językiem o bardzo silnym typie - na przykład niejawne konwersje typów nigdy nie są dozwolone w Go, nawet upCast z int
do int64
musi być jawny. Ale wszystkie metody list.List przyjmują puste interfejsy - wszystko jest dozwolone.
Jednym z powodów, dla których porzuciłem Pythona i przeniosłem się do Go, są tego rodzaju słabości w systemie typów Pythona, chociaż Python twierdzi, że jest „silnie wpisany” (IMO tak nie jest). Go list.List
wydaje się być rodzajem „mieszańca”, zrodzonego z C ++ vector<T>
i Pythona
List()
, i być może jest trochę nie na miejscu w samym Go.
Nie zdziwiłbym się, gdybyśmy kiedyś w niezbyt odległej przyszłości znaleźli listę.Lista przestarzała w Go, choć być może pozostanie, aby uwzględnić te rzadkie sytuacje, w których nawet przy użyciu dobrych praktyk projektowych można najlepiej rozwiązać problem z kolekcją zawierającą różne typy. A może jest po to, aby zapewnić "pomost" dla programistów z rodziny C, aby mogli poczuć się komfortowo z Go, zanim nauczą się niuansów wycinków, które są unikalne dla Go, AFAIK. (Pod pewnymi względami plasterki wydają się podobne do klas strumieniowych w C ++ lub Delphi, ale nie do końca).
Chociaż wywodzę się z Delphi / C ++ / Python, w moim początkowym kontakcie z Go wydałem się list.List
bardziej znajomy niż plasterki Go, ponieważ poczułem się bardziej komfortowo z Go, wróciłem i zmieniłem wszystkie moje listy na plasterki. Nie znalazłem jeszcze niczego, co slice
i / lub map
nie pozwalają mi na to, czego potrzebuję list.List
.
list
typ Pythona nie jest implementowany przy użyciu połączonej listy: zachowuje się podobnie do wycinka Go, czasami wymagając rozwinięcia kopii danych.