На этом шаге мы рассмотрим встраивание анонимных значний с методами в Go.
Если встроенное поле обладает методами, их можно вызывать относительно вмещающей структуры, но в качестве приемников таким методам будет передаваться анонимное поле.
/*Структура Tasks имеет два поля:
агрегированный срез со строками и встроенное значение Count*/ type Tasks struct { slice []string // Именованное поле(агрегирование) Count // Анонимное поле (встраивание) } /*В реализации метода Tasks.Add(), к методам анонимного поля типа Count можно обращаться непосредственно*/ func(tasks *Tasks) Add(tasks string){ tasks.slice = append (tasks.slice, tasks) tasks.Increment() // то же, что и: tasks.Count.Increment() } func(tasks *Tasks) Tally() int{ return int(tasks.Count) }
Определение типа Count было показано на шаге 82.
//Создается значение типа Tasks tasks:= Tasks{} //Вызываются методы Add(), Tally() и Count.IsZero() (как IsZero()) fmt.Println(tasks.IsZero(), tasks.Tally(), tasks) tasks.Add("Строка 1") tasks.Add("Строка 2") //Этот тип не имеет собственного метода String(), значение Tasks функции вывода воспроизводят понятно fmt.Println(tasks.IsZero(), tasks.Tally(), tasks)
Архив с примером можно взять здесь.
При вызове метода встроенного поля важно помнить, что в качестве приемника методу передается само встроенное поле. То есть при вызове Tasks.IsZero(), Tasks.Increment() и других методов типа Count относительно значения типа Tasks этим методам передается значение типа Count (или *Count), а не Tasks.
В этом примере тип Tasks имеет собственные методы Add() и Tally(), а также методы встроенного поля типа Count - Increment(), Decrement() и IsZero()). В типе Tasks можно переопределить любые или даже все методы типа Count, просто реализовав методы с теми же именами.
На следующем шаге рассмотрим встраивание интерфейсов в программах на языке Go.