Имплементация GO

Вопрос, почему компилятор ругается

s2.ToInt undefined (type Stringer has no field or method ToInt)

когда переменная создана через метод GetStringer

Но переменная с прямым присваиванием типа может иметь уникальный метод ToInt не имеющий сигнатуры в интерфейсе Stringer

package main

import "fmt"
import "strconv"

// Интерфейс Stringer
type Stringer interface {
    String() string
}

// Структура-реализация интерфейса
type MyString string

func (s MyString) String() string {
    return string(s)
}

func (s MyString) ToInt() int {
    res, _ := strconv.Atoi(string(s))
    return res
}

// Функция, возвращающая интерфейс
func GetStringer(s string) Stringer {
    return MyString(s)
}

func main() {
    // Получаем интерфейс из функции
    s := MyString("123")
    
    s2 := GetStringer("567")

    // Вызываем метод интерфейса
    fmt.Printf("%T, %v\n", s.String(), s.String())   //string, 123
    fmt.Printf("%T, %v\n", s.ToInt(), s.ToInt())    //int, 123
    
        // Вызываем метод интерфейса
    fmt.Printf("%T, %v\n", s2.String(), s2.String())  //string, 567
    fmt.Printf("%T, %v\n", s2.ToInt(), s2.ToInt())    // s2.ToInt undefined (type Stringer has no field or method ToInt)
    
}```

Ответы (1 шт):

Автор решения: Pak Uula

В Го используется декларативная система типов. У объектов можно вызывать только те методы, которые определены в явно указанных или выводимых типах.

Для переменной s2 выводимый тип Stringer. То, что в памяти этот объект представлен типом MyString, компилятор игнорирует, так как это не декларировано.

Нужно сделать приведение типа в присваивании:

s2 := GetStringer("567").(MyString)
→ Ссылка