Как можно создать переменную структуры golang
Структуры представляют тип данных, определяемый разработчиком и служащий для представления каких-либо объектов. Структуры содержат набор полей, которые представляют различные атрибуты объекта. Для определения структуры применяются ключевые слова type и struct :
type имя_структуры struct
Каждое поле имеет название и тип данных, как переменная. Например, определим структуру, которая представляет человека:
type person struct
Структура называется person. Она имеет два поля: name (имя человека, представляет тип string) и age (возраст человека, представляет тип int).
Создание и инициализация структуры
Структура представляет новый тип данных, и мы можем определить переменную данного типа:
var tom person
С помощью инициализатора можно передать структуре начальные значения:
var tom person = person
Инициализатор представляет набор значений в фигурных скобках. Причем эти значения передаются полям структуры в том порядке, в котором поля определены в структуре. Например, в данном случае строка «Tom» передается первому полю — name, а второе значение — 23 передается второму полю — age.
Также мы можем явным образом указать какие значения передаются свойствам:
var alice person = person
Также можно использовать сокращенные способы инициализации переменной структуры:
var tom = person bob := person
Можно даже не указывать никаких значений, в этом случае свойства структуры получат значения по умолчанию:
undefined := person <> // name - пустая строка, age - 0
Обращение к полям структуры
Для обращения к полям структуры после переменной ставится точка и указывается поле структуры:
package main import "fmt" type person struct < name string age int >func main() < var tom = person fmt.Println(tom.name) // Tom fmt.Println(tom.age) // 24 tom.age = 38 // изменяем значение fmt.Println(tom.name, tom.age) // Tom 38 >
Указатели на структуры
Как и в случае с обычными переменнами, можно создавать указатели на структуры.
package main import "fmt" type person struct < name string age int >func main() < tom := person var tomPointer *person = &tom tomPointer.age = 29 fmt.Println(tom.age) // 29 (*tomPointer).age = 32 fmt.Println(tom.age) // 32 >
Для инициализации указателя на структуру необязательно присваивать ему адрес переменной. Можно присвоить адрес безымянного объекта следующим образом:
var tom *person = &person var bob *person = new(person)
Для обращения к полям структуры через указатель можно использовать операцию разыменования ( (*tomPointer).age ), либо напрямую обращаться по указателю ( tomPointer.age ).
Также можно определять указатели на отдельные поля структуры:
tom := person var agePointer *int = &tom.age // указатель на поле tom.age *agePointer = 35 // изменяем значение поля fmt.Println(tom.age) // 35
Работа со структурами в Golang
Структуры в Golang — это возможность создавать определяемый пользователем тип данных из группы полей данных с разными типами данных. Поле данных в структуре может быть объявлено со встроенными или определяемыми пользователем типами данных.
Концепцию структуры можно сравнить с объектно-ориентированным программированием, которое поддерживает композицию, но не наследование.
Объявить структуру
Мы можем представить свойства или поля любой реальной сущности в структуре. Например, у сотрудника есть такие свойства, как firstName, lastName, age, phone, address и salary. Мы можем сгруппировать эти свойства в структуру Employee , как показано ниже.
type Employee struct
Приведенное выше будет объявлять тип структуры Employee и полями. Мы также можем объявить поля данных одного типа в одной строке как поля данных, разделенные запятыми, как показано ниже.
type Employee struct
Создать экземпляр структуры
Мы можем создать экземпляр структуры, присвоив его переменной.
var emp = Employee
emp := Employee
Мы также можем создать экземпляр, используя ключевое слово new .
emp := new(Employee)
Вот полный пример кода для создания экземпляра структуры Employee и передачи значений полей данных. Мы также будем получать доступ к значениям полей данных с помощью оператора . .
package main import "fmt" type Employee struct < firstName, lastName, address string age, phone, salary int >func main() < emp := Employeefmt.Println("Employee name : ", emp.firstName, emp.lastName) fmt.Println("Employee age : ", emp.age) fmt.Println("Employee salary : ", emp.salary) fmt.Println("Employee phone : ", emp.phone) fmt.Println("Employee address : ", emp.address) >
Приведенный выше пример кода выведет следующее:
Employee name : Jhon Smith Employee age : 35 Employee salary : 50000 Employee phone : 123456789 Employee address : Newyork
Экземпляр структуры с помощью указателя
Мы можем создать экземпляр структуры, используя символ оператора адреса указателя & .
package main import "fmt" type Employee struct < firstName, lastName, address string age, phone, salary int >func main() < emp1 := &Employeefmt.Println(emp1) emp2 := &Employee fmt.Println(emp2) >
Приведенный выше пример кода выведет следующее:
Вложенные структуры
Мы можем создать структуру, содержащую в себе другую структуру. В приведенном ниже примере мы будем использовать структуру Address внутри структуры Employee для города, штата и страны сотрудника.
package main import "fmt" type Employee struct < firstName, lastName string age, phone, salary int address Address >type Address struct < city string state string country string >func main() < emp := Employee< firstName: "Jhon", lastName: "Smith", age: 35, phone: 123456789, salary: 50000, address: Address< city: "Chicago", state: "Illinois", country: "USA", >, > fmt.Println("Employee name : ", emp.firstName, emp.lastName) fmt.Println("Employee city : ", emp.address.city) fmt.Println("Employee city : ", emp.address.state) fmt.Println("Employee city : ", emp.address.country) >
Приведенный выше пример кода выведет следующее:
Employee name : Jhon Smith Employee city : Chicago Employee city : Illinois Employee city : USA
Go: Структуры
В Go нет классов и привычной реализации ООП. Вместо классов в языке используются структуры — наборы полей, имеющих название и тип данных. Объявление структуры имеет следующий вид:
type Person struct < // [название поля] [тип данных] Name string Age int >func main() < p := Personp.Name // "John" p.Age // 25 >
Структуру можно инициализировать, не передавая значения. В этом случае каждое поле примет свое «нулевое» значение:
func main() < p := Person<>p.Name // "" p.Age // 0 >
Регистр первой буквы в названии структуры и полей означает публичность точно так же, как в переменных и функциях. Если первая буква заглавная, то структуру можно инициализировать во внешних пакетах. В противном случае она доступна только в рамках текущего пакета:
type Person struct < // структура публична Name string // поле публично wallet wallet // поле приватно: можно обращаться только внутри текущего пакета >type wallet struct < // структура приватна: можно инициализировать только внутри текущего пакета id string moneyAmount float64 >
У любого поля структуры можно указать теги. Они используются для метаинформации о поле для сериализации, валидации, маппинга данных из БД и тд. Тег указывается после типа данных через бектики:
type User struct
Тег json используется для названий полей при сериализации/десериализации структуры в json и обратно:
package main import ( "encoding/json" "fmt" ) type User struct < ID int64 `json:"id"` Email string `json:"email"` FirstName string `json:"first_name"` >func main() < u := User<>u.ID = 22 u.Email = "test@test.com" u.FirstName = "John" bs, _ := json.Marshal(u) fmt.Println(string(bs)) // >
Тег validate используется Go-валидатором. В следующем примере присутствует вызов функции у структуры v.Struct(u) . Функции структур — методы — мы разберем подробно в соответствующем уроке, а пока просто посмотрите, как происходит вызов:
package main import ( "fmt" "github.com/go-playground/validator/v10" ) type User struct < ID int64 `validate:"required"` Email string `validate:"required,email"` FirstName string `validate:"required"` >func main() < // создали пустую структуру, чтобы проверить валидацию u := User<>// создаем валидатор v := validator.New() // метод Struct валидирует переданную структуру и возвращает ошибку `error`, если какое-то поле некорректно fmt.Println(v.Struct(u)) >
Key: 'User.ID' Error:Field validation for 'ID' failed on the 'required' tag Key: 'User.Email' Error:Field validation for 'Email' failed on the 'required' tag Key: 'User.FirstName' Error:Field validation for 'FirstName' failed on the 'required' tag
Задание
На сервер приходит HTTP-запрос. Тело запроса парсится и мапится в модель. Сразу работать с моделью нельзя, потому что данные могут быть неверными.
Реализуйте функцию Validate(req UserCreateRequest) string , которая валидирует запрос и возвращает строку с ошибкой «invalid request», если модель невалидна. Если запрос корректный, то функция возвращает пустую строку. Правила валидации и структура модели описаны ниже. Не используйте готовые библиотеки и опишите правила самостоятельно.
type UserCreateRequest struct < FirstName string // не может быть пустым; не может содержать пробелы Age int // не может быть 0 или отрицательным; не может быть больше 150 >
Наличие пробелов можно проверить с помощью функции strings.Contains(firstName, » «) .
Упражнение не проходит проверку — что делать?
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя
Это нормально , в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.
Полезное
что такое структура в golang
Структура в Go (или struct) — это составной тип данных, который позволяет объединить несколько переменных разных типов в одну единицу данных.
Структура имеет определенное имя и состоит из набора полей fields, которые могут быть разных типов. Для обращения к полям структуры используется оператор точки, а для создания экземпляра структуры используется ключевое слово type и имя структуры, за которым следует блок с описанием полей.
Например, так можно объявить структуру Person с полями name, age и email:
type Person struct name string age int email string >
Затем, чтобы создать новый экземпляр этой структуры, можно использовать следующий код:
p := Person name: "Alice", age: 30, email: "alice@example.com", >
Теперь переменная p содержит данные об одном человеке: его имя, возраст и адрес электронной почты. Обращение к полям структуры осуществляется через оператор точки:
fmt.Println(p.name) // "Alice" fmt.Println(p.age) // 30 fmt.Println(p.email) // "alice@example.com"