В настоящее время я изучаю 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» будет отдельной копией этой структуры. Меня немного смущает концепция указателей и то, как они работают, поэтому я не уверен, как реализовать это в своих функциях.
Ваш вопрос неясен. Когда вы говорите что-то вроде «Я пробовал использовать указатели на массив», очень неясно, о каком массиве вы говорите, или, возможно, вы путаете срезы и массивы, которые в Go являются очень разными объектами.
придирка: если у вас есть if
, который возвращается, то else
бессмысленно
@Mikael Я переписал пост, чтобы он был более конкретным по вопросу.
@BDealer ответил, что, по моему мнению, это исправление
Формулировка немного размыта (вы часто используете слово 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
}
Не могли бы вы предоставить работоспособный код (с минимальной основной функцией), чтобы показать, что вы получаете по сравнению с тем, что хотите? Формулировка вопроса немного неясна.