Я пытаюсь разобраться в Go, и меня немного сбивают с толку объявления и присваивания. Есть ли способ избавиться от второй временной переменной g3
здесь? (Другие советы также приветствуются!)
Уточнение: я хочу вернуть исходный граф, если добавление какой-либо вершины не удалось.
func (g DAG) addVertices(vs ...string) (DAG, error) {
g2 := g
for _, v := range vs {
g3, err := g2.addVertex(v)
if err != nil {
return g, err
}
g2 = g3
}
return g2, nil
}
(Остальная часть кода)
type DAG struct {
vertices []vertex
edges []edge
}
func (g DAG) addVertex(v string) (DAG, error) {
if slices.Contains(g.vertices, v) {
return g, errors.New(fmt.Sprintf("ERROR: Graph already contains vertex named \"%v\"", v))
}
if len(v) == 0 {
return g, errors.New(fmt.Sprintf("ERROR: Invalid label name: \"%v\"", v))
}
return DAG{append(g.vertices, v), g.edges}, nil
}
🤔 А знаете ли вы, что...
Go обладает небольшой и компактной синтаксической базой.
Вы можете просто переписать метод addVertices
, чтобы он принимал приемник «указателя» вместо приемника значения, таким образом, все обновления g
будут происходить на месте, и вам не придется снова возвращать объект DAG
и просто верните error
, что немного похоже на идиоматическое слово Go.
func (g *DAG) addVertices(vs ...string) error {
for _, v := range vs {
if err := g.addVertex(v); err != nil {
return err
}
}
return nil
}
func (g *DAG) addVertex(v string) error {
if slices.Contains(g.vertices, v) {
return fmt.Errorf("ERROR: Graph already contains vertex named %q", v)
}
if len(v) == 0 {
return fmt.Errorf("ERROR: Invalid label name: %q", v)
}
g.vertices = append(g.vertices, v)
return nil
}
Не забудьте зафиксировать вызов этих методов на *DAG
, т. е. на указателе на структуру, а не непосредственно на DAG
.