🩳 proposal: spec: type inferred composite literals 🩳
Вы когда-нибудь задумывались, почему можно писать вот такой код:
type T struct{ V int }
a := []*T{{0}, {1}, {2}}
b := map[string]*T{"a": {0}, "b": {1}, "c": {2}}
c := [3]T{{0}, {1}, {2}}
Но нельзя вот такой:
var x []string = {"a", "b", "c"}
var y []*T = {{0}, {1}, {2}}
var z T = {0}
Всё дело в довольно сложных правилах вывода типов для сложных типов. Ещё в первых версиях создатели языка резонно решили, что одного объявления при инициализации достаточно и нет смысла дублировать идентификатор типа для каждого элемента отдельно. Что, в свою очередь, очень помогло в табличных тестах. Но вот сделать ещё один шаг им не хватило смелости уверенности в том, что код сохранит свою читаемость. А это было и остаётся критически важно для языка.
Однако всё течёт, всё меняется, и запрос на tuples (кортежи) или их аналог регулярно всплывал в issue-трекере языка. Причину для этого запроса лучше всего описать следующим кодом:
ch := make(chan struct {
value string
err error
})
//...
ch
Вы когда-нибудь задумывались, почему можно писать вот такой код:
type T struct{ V int }
a := []*T{{0}, {1}, {2}}
b := map[string]*T{"a": {0}, "b": {1}, "c": {2}}
c := [3]T{{0}, {1}, {2}}
Но нельзя вот такой:
var x []string = {"a", "b", "c"}
var y []*T = {{0}, {1}, {2}}
var z T = {0}
Всё дело в довольно сложных правилах вывода типов для сложных типов. Ещё в первых версиях создатели языка резонно решили, что одного объявления при инициализации достаточно и нет смысла дублировать идентификатор типа для каждого элемента отдельно. Что, в свою очередь, очень помогло в табличных тестах. Но вот сделать ещё один шаг им не хватило смелости уверенности в том, что код сохранит свою читаемость. А это было и остаётся критически важно для языка.
Однако всё течёт, всё меняется, и запрос на tuples (кортежи) или их аналог регулярно всплывал в issue-трекере языка. Причину для этого запроса лучше всего описать следующим кодом:
ch := make(chan struct {
value string
err error
})
//...
ch