package main

import (
	"fmt"
)

/*
1. Интерфейс является контрактом определяющим методы,
которым обязан обладать объект и объявляется через type

type Reader interface {
	Read(p []byte) (n int, err error)
}

2. Интерфейс может быть пустым с любым типом и
объявляться через var
var i interface{} = 12

3. Интерфейс может быть списком разных типов данных
var randomsArray = [5]interface{}{"Hello world", 32, false, 33.22, 'A'}

4. Интерфейс можно попытаться привести к нужному типу
var i interface{} = 12
v, ok := i.(int); ok

5. Можно получить тип объекта присвоенного интерфейсу
i.(type)

*/

func main() {
	// specialPrint(10, 4, 5, 8, 7)
	// empty()
	do(21)
	do("hello")
	do(true)
}

func specialPrint(arg ...int) error {
	if _, err := fmt.Print(arg); err != nil {
		return err
	}
	return nil
}

func empty() {
	var i interface{} = 12

	if v, ok := i.(int); ok {
		fmt.Println(v + 12)
	}
}

func do(i interface{}) {
	switch v := i.(type) {
	case int:
		fmt.Println("Умножим на 2:", v*2)
	case string:
		fmt.Println(v + " golang")
	default:
		fmt.Printf("Я не знаю такого типа %T!\n", v)
	}
}
