Область видимости и несколько возвращаемых значений

Я пытаюсь разобраться в 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 обладает небольшой и компактной синтаксической базой.


51
1

Ответ:

Решено

Вы можете просто переписать метод 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.