Функции и методы
init() и main()
Любой фрагмент программного кода на языке Go должен быть включен в пакет, а каждая программа должна иметь пакет main с функцией main().
Пакеты на языке Go могут иметь функции init() - они все выполнятся перед main(). Причем, функции init, как и main, можно не вызывать специально.
Функции
func имяФункции (необязательныеПараметры) типНеобязательногоВозвращаемогоЗначения {
тело
}
func имяФункции (необязательныеПараметры) (необязательныеоВозвращаемыеЗначения) {
тело
}
Неопределенное количество аргументов
может быть функция с неопределенным количеством параметров
func test(a int, b ...int) {
Здесь будет b []int
}
Именованные возвращаемыее значения
Возвращаемые значения могут быть именованные и неименованные. Смешивать нельзя. Именованные возвращаемые значения рекомендуется использовать только в коротких функциях (чтобы не ухудшать читаемость кода).
Пример:
func split(sum int) (x, y int) {
x = sum * 4 / 9
y = sum - x
return
}
На текущий момент компиляторы не способны распознать return в секции default или else безусловном. Принято в таких случаях использовать panic("unreachable")
Передача параметров из одной функции в другую
// Обрати вниманиее на компактное указание одинаковых типов
func test(a, b, c int) bool {
return true
}
func test1(r int) (int, int, int) {
return 1, 2, 3
}
dont := test(test1(1))
Необязательные параметры
В Go нет поддержки необязательных параметров. Однако, этого можно добиться использованием структур, которые инициализируются по умолчанию.
type Options struct {
First int
Audit bool
ErrorHandler func(item Item)
}
func test(items Items, options Options) {
...
}
test(items, Options{})
test(items, Options{ErrorHandler: errorHandler})
Выбор функции во время выполнения
Ветвление с помощью отображений и ссылок на функции
var FunctionForSuffix = map[string]func(string) ([]string, error) {
".gz": GzipFileList,
".tar": TarFileList,
...
}
Методы
Примеры
Пример метода, переопределяющего функцию len для типа Stack. Имя stack (может быть любым) в терминах Go называется приемником (в других языках это имя фиксировано - this, self,..).
func (stack Stack) Len() int {
return len(stack)
}
Если метод должен изменять значение приемника, его необходимо определить как указатель. В противном случае, в метод передается копия объекта.
func (obj *Test) Method(x interface{}) {
someLocalObj := *obj
*obj = append(*obj, x)
}
Возвращение нескольких значений
func (test Test) Top() (interface{}, error) {
if len(test) == 0 {
return nil, errors.New("blabla")
}
return test, nil
}
Ограничения
Имена всех методов должны быть уникальны в пределах одного типа. Следовательно, нельзя создать два одинаковых метода - один для значения, другой для указателя.
Отсутствует поддержка перегруженных методов. Один способов реализовать подобие перегруженных методов - использовать методы с переменным числом аргументов, однако в Go принято использовать функции с уникальными именами. Например тип strings.Reader представляет три разных метода чтения: strings.Reader.Read(), strings.Reader.ReadByte(), strings.Reader.ReadRune().
Множество методов значения - все методы этого типа, принимающие приемник по значению. Множество методов указателя - все методов этого типа, принимающий приемник по значению и по указателю!
Переопределение методов
type Item struct {
id int
}
func (item *Item) GetID() int {
return id
}
type SpecialItem struct {
Item
catalogId int
}
func (item *SpecialItem) GetID() int {
return item.Item.GetID() + item.catalogId
}
item := Item{1}
special := SpecialItem{Item{2}, 3}
/*
item.id == 1
special.id == 2
special.catalogId == 3
special.GetID() == 5
special.Item.GetID() == 2
*/
Конструкторы
Конструкторы - это функции, возвращающие проинициализированне значение. Их принято называть New...
type Place struct {
cost int // private
Name string // public
}
func New(name string) *Place {
return &Place{0, name}
}
func NewPlaceWithCost(name string, cost int) *Place {
return &Place{cost, name}
}
func (place Place) Cost() int {
// сделать необходимые проверки
return place.cost
}
Анонимная функция (замыкания)
Пример:
some.Func(func(word string) string { return word })
Для чего используются
Создание функций-оберток
addPng := func(name string) string { return name + ".png" }
Создание фабричных функций
фабричные функции - такие функции, которые возвращают другие функции
func MakeAddSuffix(suffix string) func(string) string {
return func(name string) string {
if !strings.HasSuffix(name, suffix) {
return name + suffix
}
return name
}
}
addZip := MakeAddSuffix(".zip")
fmt.Println(addZip("filename"))
Last updated