golang book 10

для проверки количества символов в строке подключаем unicode/utf8 if utf8.RuneCountInString(title) > 20 packege calendarmark import ( "unicode/utf8" "my/date" ) type Event struct { title String Date } func (e *Event) Title() string { return e.title } func (e *Event) Title(title string) string { if utf8.RuneCountInString(title) > 20 { return errors.New("invalit title") } etitle = title return nill } Интерфейсы это набор средств для взаимодействия с программой type MyInterface interfacee { method1() method2(float64) что получает method3() string что возвращает } обьявляем переменные, использующие интерфейс var value mypkg.MyInterface value.method1() интерфейс просто описывает, какие методы обязательно содержать package main import "fmt" type Whistle string func (w Whistle) MakeSound() { fmt.Println("Tweet!") } type Horn string func (h Horn) MakeSound() { fmt.Println("Honk!") } type NoiseMaker interface{ MakeSound() } func main() { var toy NoiseMaker // Хоть тут тип интерфейс toy = Whistle("Toyco Canary") // Все равно присваиваем переменную toy.MakeSound() toy = Horn("Toyco Blaster") toy.MakeSound() } еще интерфейс блокирует доступ к сторонним функциям при присвоение в интерфейс интерфейс = что-то мы можем вызывать только функции интерфейса Утверждение типа как я понял, это передача данных интерфейса в тот же тип var mark1 Marker = Robot("12") var robot Robot = Marker.(Robot) robot, ok := Marker.(Robot) ok true false если доставать не тот тип из интерфейса, то именно во время выполнения (не компиляции) будет паника при таком возврате, есть второе возвращаемое значение где если true то все норм передалось false все пошло не как надо и если ок, то используем необходимые функции error это тоже интерфейс, который есть по умолчанию package main import ( "fmt" "log" ) type OverError float64 func (o OverError) Error() string { return fmt.Sprintf("Over %02f", o) } func checkTemperature(actual float64, safe float64) error { excess := actual - safe if excess > 0 { return OverError(excess) } return nil } func main() { var err error = checkTemperature(121.379, 100.0) if err != nil { log.Fatal(err) } } по правилам этикета в тип необходимо добавлять метод Stringer для красивого вывода 376 так же рно воспринимается по умолчанию для вывода type Milliliters float64 func (m Milliliters) String() string { return fmt.Sprintf("%0.2f mL", m) } func main() { fmt.Println(Gallons(12.09248342)) fmt.Println(Liters(12.09248342)) fmt.Println(Millilite rs(12.09248342)) } для документаций go doc interface{} пустой интерфейс это для передачи значения любого типа в функцию интерфейс не описывает что, он говорит только действия 383 os.Args содержит все аргументы запуска программы всегда закрывайте файлы при чтении чтоб экономить ресурсы defer она откладывает действие на момент завершения функции либо программы package main import "fmt" func Socialize() { defer fmt.Println("1") defer fmt.Println("2") fmt.Println("3") fmt.Println("4") } func main() { Socialize() Socialize() } 34213421 defer пофигу на return и они закрываются снизу вверх и вызывается до вывода ошибки программа для сумиирования float64 с файла sumFloat64File.go package main import ( "bufio" "fmt" "log" "os" "strconv" ) func OpenFile(fileName string) (*os.File, error) { fmt.Println("Opening ", fileName) return os.Open(fileName) } func CloseFile(file *os.File) { fmt.Println("Closing file") file.Close() } func GetFloats(fileName string) ([]float64, error) { var numbers []float64 file, err := OpenFile(fileName) if err != nil { return nil, err } defer CloseFile(file) scaner := bufio.NewScanner(file) for scaner.Scan() { number, err := strconv.ParseFloat(scaner.T> if err != nil { return nil, err } numbers = append(numbers, number) } if scaner.Err() != nil { return nil, scaner.Err() } return numbers, nil } func main() { numbers, err := GetFloats(os.Args[1]) if err != nil { log.Fatal(err) } var sum float64 = 0 for _, number := range numbers { sum += number } fmt.Printf("Sum: %0.2f\n", sum) } 385