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