Пара вопросов про интерфейсы.

52 views
Skip to first unread message

Inno Bragovich

unread,
Jan 8, 2018, 3:13:49 PM1/8/18
to Golang Russian
Всем доброго времени суток!
Помогите, пожалуйста, осмыслить про интерфейсы.

У меня два вопроса.
1)Почему происходит ошибка, если в методе для структуры передать не структуру, а указатель на структуру?
Как быть, если я хочу, чтобы метод структуры изменял какое-либо её поле в этой структуре, а не только внутри тела метода?
(см. в ниже коде функцию ChangeName)

2)Почему, когда я инициализирую интерфейс, и затем литералу присваиваю структуру, то в коде не видно полей этой структуры (не смотря на то, что все данные присутствуют) ? Ошибка возникает на последней строке функции main. Со структурами, которые не "наследуют" интерфейс, такого не происходит, они работают нормально.

package main

import "fmt"
import "reflect"

type NameChanger interface {
ChangeName()
}

type man struct {
Name  string
Name2 string
}

func (m man) ChangeName() { //Почему я не могу здесь написать  func (m *man) ChangeName() ?
m.Name = string("New Name")
}

func main() {
a := man{Name: "Ivan", Name2: "Petrov"}
fmt.Printf("type=%v, value=%v\n", reflect.TypeOf(a), a) //type=main.man, value={Ivan Petrov}
a.ChangeName()
fmt.Printf("type=%v, value=%v\n", reflect.TypeOf(a), a.Name) //type=main.man, value=Ivan

var b NameChanger
b = man{Name: "Sergey", Name2: "Smirnov"}
fmt.Printf("type=%v, value=%v\n", reflect.TypeOf(b), b) //type=main.man, value={Sergey Smirnov}
b.ChangeName()
fmt.Printf("type=%v, value=%v\n", reflect.TypeOf(b), b.Name) //b.Name undefined (type NameChanger has no field or method Name)
}



Daniel Podolsky

unread,
Jan 8, 2018, 3:52:02 PM1/8/18
to gola...@googlegroups.com
на самом деде - все работает

https://play.golang.org/p/KnxiFLfXbLL

тут такое дело: если вы зовете метод интерфейса - его надо звать с
правильным ресивером. метод с указателем надо звать от указателя.
иначе ни компайлер, ни линтеры не разберутся никогда, что имелось в
виду...
> --
> Вы получили это сообщение, поскольку подписаны на группу "Golang Russian".
> Чтобы отменить подписку на эту группу и больше не получать от нее сообщения,
> отправьте письмо на электронный адрес
> golang-ru+...@googlegroups.com.
> Чтобы настроить другие параметры, перейдите по ссылке
> https://groups.google.com/d/optout.

Inno Bragovich

unread,
Jan 8, 2018, 5:15:34 PM1/8/18
to Golang Russian
Хорошо, а что с последней строчкой ?

Andrey Velikoredchanin

unread,
Jan 8, 2018, 5:31:25 PM1/8/18
to golang-ru
9 января 2018 г., 1:15 пользователь Inno Bragovich <innobr...@gmail.com> написал:

Хорошо, а что с последней строчкой ?

Если вы объявляете переменную в качестве интерфейса, вы можете использовать только методы этого интерфейса. Либо сделать преобразование типа а-ля obj := b.(man)
 

Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес golang-ru+unsubscribe@googlegroups.com.

Inno Bragovich

unread,
Jan 8, 2018, 6:21:16 PM1/8/18
to Golang Russian
Можете сказать, как эдакая конструкция называется? чё-то не встречал

Andrey Velikoredchanin

unread,
Jan 8, 2018, 6:34:25 PM1/8/18
to golang-ru
Преобразование типов. Обычно оно встречается не отдельно, а в составе конструкции switch b.(type). И тогда нужное преобразование можно сделать без риска получить runtime ошибку.

9 января 2018 г., 2:21 пользователь Inno Bragovich <innobr...@gmail.com> написал:
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес golang-ru+unsubscribe@googlegroups.com.

Inno Bragovich

unread,
Jan 8, 2018, 6:36:10 PM1/8/18
to Golang Russian
Спасибо, погуглю.

Andrey Velikoredchanin

unread,
Jan 8, 2018, 6:36:11 PM1/8/18
to golang-ru

9 января 2018 г., 2:34 пользователь Andrey Velikoredchanin <uncle...@gmail.com> написал:
Reply all
Reply to author
Forward
0 new messages