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

Я новичок в 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?

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

1 ответ

Решение

Проблема в том, что 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 это набор всех методов, объявленных с получателем *T или же T (то есть, он также содержит набор методов T).

За кулисами

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

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

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

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

Другие вопросы по тегам