Получение указателя среза и возврат указателей на элементы этого среза

В настоящее время я изучаю GO и решил в качестве упражнения переделать ранкер персонажей, который сделал на Python год назад. Программа принимает вводимые пользователем данные и создает из них фрагмент структур (структура состоит из введенного имени и значения 0), затем функция создает совпадения между введенными символами, чтобы пользователь мог выбирать между двумя парами. полный код здесь


type Char struct {
    Name  string
    Score uint8
}

func main() {
    baseSlice := InputCharacters()
    matchups := MatchMaking(baseSlice)
    voting := Voting(matchups)
    n := 0
    for _, v := range voting {
        fmt.Printf("%d: %v(%v)\n", n, v.Name, v.Score)
        n++
    }
    /* the for returns 2 copies of each character,
       none of them have any points */

}

func InputCharacters() []structs.Char {

    var charSlice []structs.Char = []structs.Char{}
    var reader = bufio.NewReader(os.Stdin)

    for {

        fmt.Println("Enter a character name (or quit/q to finish):")

        name, err := reader.ReadString('\n')
        name = strings.TrimSpace(name)
        if err != nil {
            fmt.Printf("Reading error: %v", err)
        }

        if name == "quit" || name == "q" {
            return charSlice
        }

        for i := range charSlice {
            if charSlice[i].Name == name {
                charSlicePostDelete := structs.RemoveElement(charSlice, i)
                charSlice = charSlicePostDelete
                break
            }
        }

        charSlice = append(charSlice, structs.Char{Name: name, Score: 0})

    }
}

func MatchMaking(arr []structs.Char) map[[2]structs.Char]bool {
    m := make(map[[2]structs.Char]bool)
    for _, v1 := range arr {
        for _, v2 := range arr {
            pair := [2]structs.Char{v1, v2}

            if pair[0].Name == pair[1].Name {
                continue
            }

            sortedPair := [2]structs.Char{SortAlphabetically(pair[0], pair[1]), SortAlphabeticallyReverse(pair[0], pair[1])}
            if _, ok := m[sortedPair]; !ok {
                m[sortedPair] = true
            }
        }
    }
    return m
}

func Voting(pairs map[[2]structs.Char]bool) []structs.Char {

    var reader = bufio.NewReader(os.Stdin)

    for i := range pairs {
        fmt.Println("Vote for your favourite (0 for left, 1 for right)")
        fmt.Printf("%v - %v\n", i[0].Name, i[1].Name)
        name, err := reader.ReadString('\n')
        name = strings.TrimSpace(name)
        if err != nil {
            fmt.Printf("Reading error: %v", err)
        }
        nameToInt, err := strconv.ParseInt(name, 0, 8)
        if err != nil {
            fmt.Printf("Reading error: %v", err)
        }
        switch nameToInt {
        case 0:
            i[0].Score = i[0].Score + 1
        case 1:
            i[1].Score = i[1].Score + 1
        }
    }

    var charArr []structs.Char = make([]structs.Char, 0, len(pairs)*2)
    for i := range pairs {
        charArr = append(charArr, i[0], i[1])
    }
    return charArr

}


func SortAlphabetically(a, b structs.Char) structs.Char {
    if a.Name < b.Name {
        return a
    }
    return b
}

func SortAlphabeticallyReverse(a, b structs.Char) structs.Char {
    if a.Name > b.Name {
        return a
    }
    return b
}

Я хочу, чтобы функция Matchmaking возвращала указатели на элементы исходного []structs.Char вместо копий, чтобы я мог затем изменить свойство Оценка в другой функции, и это изменение будет видно в исходном фрагменте. Вместо этого функция MatchMaking() возвращает разные копии структуры char для каждого типа, который необходим экземпляр структуры, поэтому, если Mathmaking возвращает две пары со структурой «c», каждая «c» будет отдельной копией этой структуры. Меня немного смущает концепция указателей и то, как они работают, поэтому я не уверен, как реализовать это в своих функциях.

Не могли бы вы предоставить работоспособный код (с минимальной основной функцией), чтобы показать, что вы получаете по сравнению с тем, что хотите? Формулировка вопроса немного неясна.

Mikael 08.08.2024 21:42

Ваш вопрос неясен. Когда вы говорите что-то вроде «Я пробовал использовать указатели на массив», очень неясно, о каком массиве вы говорите, или, возможно, вы путаете срезы и массивы, которые в Go являются очень разными объектами.

Gimby 09.08.2024 10:14

придирка: если у вас есть if, который возвращается, то else бессмысленно

Elias Van Ootegem 09.08.2024 11:15

@Mikael Я переписал пост, чтобы он был более конкретным по вопросу.

BDealer 09.08.2024 12:19

@BDealer ответил, что, по моему мнению, это исправление

Mikael 09.08.2024 17:36
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
4
5
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Формулировка немного размыта (вы часто используете слово return в контекстах, где, как мне кажется, вы имеете в виду использование или передачу), но я считаю, что вы хотите изменить базовые значения в структурах Char. Для этого мы будем использовать указатели на Char*Char (в данном случае карту пар от *Char до bool) как в методах MatchMaking, так и в Voting. Таким образом, любые изменения, которые вы делаете, распространяются на базовые структуры, поскольку теперь вы передаете указатели вместо копий структур.

func MatchMaking(arr []Char) map[[2]*Char]bool {
    m := make(map[[2]*Char]bool)
    for i := 0; i < len(arr); i++ {
        for j := i + 1; j < len(arr); j++ {
            pair := [2]*Char{&arr[i], &arr[j]}

            if pair[0].Name == pair[1].Name {
                continue
            }

            sortedPair := [2]*Char{SortAlphabetically(pair[0], pair[1]), SortAlphabeticallyReverse(pair[0], pair[1])}
            if _, ok := m[sortedPair]; !ok {
                m[sortedPair] = true
            }
        }
    }
    return m
}

func Voting(pairs map[[2]*Char]bool) []Char {
    var reader = bufio.NewReader(os.Stdin)

    for i := range pairs {
        fmt.Println("Vote for your favourite (0 for left, 1 for right)")
        fmt.Printf("%v - %v\n", (*i[0]).Name, (*i[1]).Name)
        name, err := reader.ReadString('\n')
        name = strings.TrimSpace(name)
        if err != nil {
            fmt.Printf("Reading error: %v", err)
        }
        nameToInt, err := strconv.ParseInt(name, 0, 8)
        if err != nil {
            fmt.Printf("Reading error: %v", err)
        }
        switch nameToInt {
        case 0:
            (*i[0]).Score++
        case 1:
            (*i[1]).Score++
        }
    }

    var charArr []Char = make([]Char, 0, len(pairs)*2)
    for i := range pairs {
        charArr = append(charArr, *i[0], *i[1])
    }
    return charArr
}

Другие вопросы по теме