Можно ли передать интерфейс 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
поэтому этот случай будет выполнен.