Можно ли передать интерфейс obj типу интерфейса {}?

pointers go types interface go-interface

86 просмотра

1 ответ

64 Репутация автора

Я новичок в golang и хочу реализовать перегруженный метод, похожий на перегрузку C ++, и мой код выглядит примерно так:

type someStruct struct {
    val  int
    some string
}

type object interface {
    toByte()
}

// someStruct implementing an object interface
func (s *someStruct) toByte() {
}

func overload(overLoadedObj interface{}) {

    switch str := overLoadedObj .(type) {
    case string:
        fmt.Println("string : ", str)
    case int:
        fmt.Println("int : ", str)
    case object: //* It doesn't come here at all*
        fmt.Println("interface obj", str)
    }
}

func main() {
    overload("hello")
    overload(5)
    overload(someStruct{val: 5, some: "say"})
}

Итак, вопрос в следующем:

Как убедиться, что тот, кто реализует интерфейс объекта , попадет под тип объекта case ?

Заранее спасибо.

Автор: Ronin Goda Источник Размещён: 18.07.2016 06:14

Ответы (1)


2 плюса

205945 Репутация автора

Решение

«Проблема» в том, что someStruct.toByte()есть указатель приемника. Это означает, что метод toByte()принадлежит типу, *someStructа не к someStruct. Так someStructчто не реализует object, только *someStruct. И вы передаете значение someStructв overload().

Передайте значение *someStruct, и вы получите то, что хотите:

overload(&someStruct{val: 5, some: "say"})

Вывод (попробуйте на Go Playground ):

string :  hello
int :  5
interface obj &{5 say}

Соответствующий раздел из спецификации: Метод устанавливает :

Тип может иметь набор методов, связанный с ним. Набор методов типа интерфейса является его интерфейсом. Набор методов любого другого типа Tсостоит из всех методов, объявленных с типом получателя T. Набор методов соответствующего типа указателя *T является набором всех методов, объявленных с помощью receive *Tили T(то есть он также содержит набор методов T).

За кулисами

Обратите внимание, что за кадром, когда вы звоните overload()так:

overload(&someStruct{val: 5, some: "say"})

Это обернет *someStructзначение указателя в interface{}значение (потому что overload()имеет параметр interface{}типа), а не в значение типа интерфейса object.

Внутри overload(), то переключатель типа будет проверять типы в указанном порядке. И когда он достигает case object, он увидит, что значение, заключенное в overLoadedObjпараметр, реализует, objectпоэтому этот случай будет выполнен.

Автор: icza Размещён: 18.07.2016 06:29
Вопросы из категории :
32x32