Интерфейс как параметр в Go
Функция может принимать интерфейс и вызывать его метод, не зная конкретный тип. В параметре виден только список методов, а внутрь можно передать любое значение, у которого этот список есть. Так сценарий отделяют от конкретной структуры.
Напишем функцию, которая запускает печать у переданного значения:
package main
import "fmt"
type Printer interface {
Print()
}
type Doc struct {
Title string
}
func (d Doc) Print() {
fmt.Println(d.Title)
}
type Label struct {
Text string
}
func (l Label) Print() {
fmt.Println(l.Text)
}
func Run(p Printer) {
p.Print()
}
func main() {
Run(Doc{Title: "note"})
Run(Label{Text: "tag"})
}
Run не упоминает Doc и
Label в сигнатуре. Оба значения
подошли под Printer, поэтому вызовы
собрались. Внутри Run срабатывает
тот Print, который принадлежит
фактическому типу аргумента.
Такой прием удобен, когда одно действие повторяют для разных типов. Новый тип достаточно снабдить нужным методом, и старый код функции менять не нужно.
Дан интерфейс Greeter с методом
Greet, возвращающим string.
Напишите функцию Show с параметром
Greeter, которая выводит результат
приветствия.
Дан следующий код:
package main
import "fmt"
type Printer interface {
Print()
}
type Page struct {
Body string
}
func (p Page) Print() {
fmt.Println(p.Body)
}
func Run(p Printer) {
p.Print()
}
Вызовите Run с Page, у
которого Body равно "hello".
Скажите, можно ли передать в Run
значение типа int без метода
Print.