Почему я получаю пустую переменную со ссылкой на интерфейс? - PullRequest
0 голосов
/ 04 ноября 2018
package main

import (
    "fmt"
    "net/http"
    "sync"
    "time"
)

type myInterface interface {
    doFunc() bool
}

type myStruct struct {
    myValue string
    si            myInterface 
}

func newStrcut(si myInterface ) *myStruct {
    return &myStruct {si: si}
}

var myS *myStruct 

func main() {

    myS = newStrcut(&newStrcut{})
    myS.myValue = "test"
    if myS.doMyLogic() {
        return
    }

}

func (s *myStruct) doMyLogic() bool {
    fmt.Printf(s.myValue )
    s.si.doFunc()
    return false
}

func (s *myStruct) doFunc() bool {
    fmt.Printf(s.myValue)
    return false
}

Почему я получаю разные значения для s.MyValue в doFunc и doMyLogic? В doMyLogic это было test, а в doFunc - "".

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Джереми рассказал, почему он не работает . Я думаю, что могу ответить на то, что ОП хочет сделать. Я думаю, что есть недоразумение о том, как работают интерфейсы. Я думаю, что ОП пытается дать myStruct интерфейс myInterface, но интерфейсы неявные.

type myInterface interface {
    doFunc() bool
}

Это делает интерфейс myInterface. Вещи не должны быть объявлены как интерфейс. Все, что удовлетворяет интерфейсу, является этим интерфейсом. Все, что определяет doFunc() bool, является myInterface. Нет необходимости декларировать это.

Я хочу, чтобы myValue была одинаковой для тех же объектов в той же структуре - user1365697 15 минут назад

Идея состоит в том, чтобы создать интерфейс, а затем использовать его из тестов и вызвать тот же метод, который создает myValue, а затем отправить соответствующую структуру - user1365697 13 минут назад ОП в комментарии

type myStruct struct {
    myValue string
    si            myInterface 
}

Это определяет структуру, которая имеет строку, и она также имеет что-то, что реализует myInterface. Опять же, это все, что определяет doFunc() bool.

Важно понимать, что myStruct.si - это совершенно другая вещь (возможно, потому что она не определена) со своими myValue.

Вместо того, чтобы давать myStruct свою собственную дополнительную структуру, я думаю, что OP намеревался дать myStruct myInterface интерфейс. Поскольку интерфейсы неявные myStruct уже удовлетворяют myInterface. Это должно выглядеть так:

package main

import (
    "fmt"
)

type myInterface interface {
    doFunc() bool
}

type myStruct struct {
    myValue string
}

func (s myStruct) doMyLogic() bool {
    fmt.Println(s.myValue)
    s.doFunc()
    return false
}

func (s myStruct) doFunc() bool {
    fmt.Println(s.myValue)
    return false
}

func main() {
    myS := myStruct{ myValue: "test" }
    if myS.doMyLogic() {
        return
    }
}

Поскольку myStruct имеет doFunc() bool, он удовлетворяет интерфейсу myInterface. Для этого не нужно добавлять дополнительное поле.

Вы можете передать myStruct всему, что требует myInterface. Это идея интерфейсов. Вместо того, чтобы делать явные объявления, все, что удовлетворяет интерфейсу, будет работать. Как и Утиное печатание, но строгое.

func usesMyInterface(s myInterface) bool {
    return s.doFunc()
}

func main() {
    myS := myStruct{ myValue: "test" }
    usesMyInterface(myS)
}
0 голосов
/ 04 ноября 2018

Вы получаете доступ к полю MyValue на двух разных объектах. Ваш код создает объект, myS, который содержит указатель на второй объект, myS.si.

Первый содержит "test" в поле MyValue. Другой, так как он никогда не был установлен, получает значение по умолчанию для строк, "".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...