@to_east

Структуры, указатели, массивы?

Приветствую участников тостера!
Объясните пожалуйста кое какие вещи. Вот мне необходимо сделать массив структур, причем каждый элемент массива имел экшен, тут видимо какая-то магия с указателями, которую я пока что непрочувствовал. Вобщем код:
package main

import "fmt"


type nextWords struct {
    words []string
}

func (nw *nextWords) GetFirstItem() string {
    return nw.words[0]
}

func main() {
    var myMap = make(map[string]nextWords)
    myMap["hello"] = nextWords{words: []string{"foo", "bar"}}

    fmt.Println(myMap["hello"].GetFirstItem())
}

Компилятор ругается на:
C:\Windows\system32\cmd.exe /c (go run test1.go ^& pause)
# command-line-arguments
.\test1.go:18: cannot call pointer method on myMap["hello"]
.\test1.go:18: cannot take the address of myMap["hello"]
Для продолжения нажмите любую клавишу . . .
  • Вопрос задан
  • 385 просмотров
Решения вопроса 1
В данном случае вам нужно положить в мапу указатели на вашу структуру.
https://play.golang.org/p/Jn18TTSDh5T
package main

import "fmt"

type nextWords struct {
	words []string
}

func (nw *nextWords) GetFirstItem() string {
	return nw.words[0]
}

func main() {
	var myMap = make(map[string]*nextWords)
	myMap["hello"] = &nextWords{words: []string{"foo", "bar"}}

	fmt.Println(myMap["hello"].GetFirstItem())
}


Второй вариант, объявить метод как вызываемый на значении, а не указателе.

Ваш метод GetFirstItem объявлен как вызываемый на указателе (nw *nextWords), поэтому его можно вызвать только на элементе, от которого го может получить адрес. Из мапы его не получается взять потому что при взятии мы получаем копию этого элемента, а не сам элемент. Инплейс го не может взять в таком случае указатель на структуру, разве что мы сначала вытащим её из мапы в переменную и вызовем метод на ней (например так)
Когда мы делаем мапу из указателей, мы получаем из неё копию указателя, а не самой структуры и можем вызвать на этом указателе метод.

Но учтите, что при отсутствии элемента в мапе ваша программа свалится в панику, поэтому в методе GetFirstItem стоит сделать проверку на nil.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@to_east Автор вопроса
Ясно, благодарю за подробные разъяснения!
Выходит нужно создавать массив указателей на nextWords структуру.

разве что мы сначала вытащим её из мапы в переменную и вызовем метод на ней

Кстати только что получилось такое проделать, на основе этого хотел сделать вызов (&myMap["hello"]).GetFirstItem() такого рода, но тоже фэйл вышел
Ответ написан
Комментировать
@KirEv
почему именно map? больше бы контекста, это для себя или часть другой задачи?

предполагаю, с этим массивов структур нужно будет выполнить какие-то действия, если нет необходимости в ассоциативном массиве, по моему, лучше не использовать map

без мапинга
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы