πŸƒ Π‘Π°ΠΌΠΎΡƒΡ‡ΠΈΡ‚Π΅Π»ΡŒ ΠΏΠΎ Go для Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ…. Π§Π°ΡΡ‚ΡŒ 7. ΠœΠ°ΡΡΠΈΠ²Ρ‹ ΠΈ слайсы. Append ΠΈ сopy. ΠŸΠ°ΠΊΠ΅Ρ‚ slices

Рассмотрим Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ массивов ΠΈ слайсов Π² языкС Go, Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ append ΠΈ copy, ΠΈΠ·ΡƒΡ‡ΠΈΠΌ ΠΏΠ°ΠΊΠ΅Ρ‚ slices ΠΈ ΠΏΠΎ Ρ‚Ρ€Π°Π΄ΠΈΡ†ΠΈΠΈ Ρ€Π΅ΡˆΠΈΠΌ нСсколько Π·Π°Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡.

ΠœΠ°ΡΡΠΈΠ²Ρ‹

ΠœΠ°ΡΡΠΈΠ²Ρ‹ Π² Go

ΠœΠ°ΡΡΠΈΠ²Ρ‹ Π² Go ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой Ρ„ΠΈΠΊΡΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ Π΄Π°Π½Π½Ρ‹Ρ… Π·Π°Π΄Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°. Π’Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ памяти для массива происходит Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π΅Π³ΠΎ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, Π° хранится ΠΎΠ½ Π² Π½Π΅ΠΉ ΠΊΠ°ΠΊ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ Π±Π»ΠΎΠΊΠΎΠ² ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ Ρ‚ΠΈΠΏΠ°.

Рассмотрим нСсколько способов создания массива Π² Go:

  • Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова var ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π³ΠΎ присвоСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ:
var arr1 [2]int
arr1[0] = 0
arr1[1] = 1

var users [2]string
users[0] = "ΠŸΠ΅Ρ‚Ρ"
users[1] = "Π“ΠΎΡˆΠ°"
  • Π‘ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Π΄Π»ΠΈΠ½Ρ‹ массива ΠΈ входящих Π² Π½Π΅Π³ΠΎ элСмСнтов:
arr2 := [3]int{0, 1, 2}
  • Π‘ пСрСчислСниСм элСмСнтов, Π½ΠΎ Π±Π΅Π· указания Π΄Π»ΠΈΠ½Ρ‹, которая Π±ΡƒΠ΄Π΅Ρ‚ автоматичСски подсчитана компилятором:
arr3 := [...]bool{true, false, true}
  • Для создания N-ΠΌΠ΅Ρ€Π½ΠΎΠ³ΠΎ массива Π½ΡƒΠΆΠ½ΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π΄Π»ΠΈΠ½Ρƒ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ измСрСния, Ρ‚ΠΈΠΏ ΠΈ Π² скобках {} ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»ΠΈΡ‚ΡŒ элСмСнты:
arrND := [len1][len2][len3]....[lenN]T{}

НапримСр, Ρ‚Π°ΠΊ создаСтся Π΄Π²ΡƒΠΌΠ΅Ρ€Π½Ρ‹ΠΉ массив с цСлочислСнными элСмСнтами:

arr2D := [2][2]int{
	{1, 2},
	{3, 4},
}
fmt.Println(arr2D) // [[1 2] [3 4]]

Π‘Ρ‚ΠΎΠΈΡ‚ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ массивы Ρ€Π°Π·Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Ρ‹ ΠΈΠΌΠ΅ΡŽΡ‚ Ρ€Π°Π·Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Ρ€Π°Π·ΠΌΠ΅Ρ€ массива Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ°:

arr3 := [3]int{1, 2, 3}
arr4 := [3]int{1, 2, 3}
fmt.Println(arr3 == arr4) // true

// ошибка: массивы ΠΈΠΌΠ΅ΡŽΡ‚ Ρ€Π°Π·Π½ΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ
arr1 := [3]int{1, 2, 3}
arr2 := [2]int{1, 2}
fmt.Println(arr1 == arr2) // mismatched types [3]int and [2]int

ЗначСния массива ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Π² Ρ†ΠΈΠΊΠ»Π΅:

arr := [3]string{"alpha", "beta", "gamma"}
for ind, val := range arr {
	fmt.Printf("Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ с индСксом %d: %s\\n", ind, val)
}
// Π’Ρ‹Π²ΠΎΠ΄:
// Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ с индСксом 0: alpha
// Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ с индСксом 1: beta
// Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ с индСксом 2: gamma

Аналогичная конструкция, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰Π°Ρ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ len() для вычислСния Π΄Π»ΠΈΠ½Ρ‹ массива:

for i := 0; i < len(arr); i++ {
	fmt.Printf("Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ с индСксом %d: %s\\n", i, arr[i])
}

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ с массивами Π½ΡƒΠΆΠ½ΠΎ всСгда ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° ΠΈΡ… Π΄Π»ΠΈΠ½ΠΎΠΉ ΠΈ Π½Π΅ Π΄ΠΎΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ обращСния ΠΊ постороннСй области памяти. ΠŸΡ€ΠΈ Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π·Π° Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ массива компилятор сообщит ΠΎΠ± ошибкС index out of range:

// ошибка - index out of range [3] with length 3
arr := [3]string{"alpha", "beta", "gamma"}
for i := 0; i < 4; i++ {
	fmt.Printf("Π­Π»Π΅ΠΌΠ΅Π½Ρ‚ с индСксом %d: %s\\n", i, arr[i])
}
πŸ‘¨β€πŸ’» Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°Β»
πŸŽ“ Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go для собСса
ΠŸΠΎΠ΄Ρ‚ΡΠ½ΡƒΡ‚ΡŒ свои знания ΠΏΠΎ Go Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Go для собСса»
🧩 Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ Go
Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ ΠΏΠΎ Go для ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΉΡ‚ΠΈ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΏΠΎ GoΒ»

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ массивов Π² Go

Π’ Go массивы ΡΠ²Π»ΡΡŽΡ‚ΡΡ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌΠΈ значСниями, поэтому ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ ΠΈΠ»ΠΈ присваивании массивов создаСтся копия ΠΈΡ… содСрТимого. ΠΠ»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для избСТания копирования Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² использовании ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° массив, ΠΊΠ°ΠΊ это дСлалось с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… ΡƒΡ€ΠΎΠΊΠ°Ρ….

Π§Ρ‚ΠΎΠ±Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅ ΠΏΠΎΠ½ΡΡ‚ΡŒ эту ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ, обратимся ΠΊ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌΡƒ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ. Π’ ΠΊΠΎΠ΄Π΅ Π½ΠΈΠΆΠ΅ массив result копируСтся ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ changeArray, поэтому всС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ увСличСния производятся Π½Π°Π΄ массивом arr, Π° result остаСтся Π±Π΅Π· измСнСния.

func changeArray(arr [3]int, elem int) {
	for i := 0; i < len(arr); i++ {
		arr[i] += elem
	}
}

func main() {
	result := [3]int{1, 2, 3}
	changeArray(result, 100)
	fmt.Println(result) // 1 2 3
}

Для измСнСния массива result слСдуСт ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ changeArrayPtr, которая, Π² ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ changeArray, Π² качСствС ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π½Π΅ просто массив, Π° ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π½Π΅Π³ΠΎ:

func changeArrayPtr(arr *[3]int, elem int) {
	for i := 0; i < len(arr); i++ {
		arr[i] += elem
	}
}

func main() {
	arr := [3]int{1, 2, 3}
	changeArrayPtr(&arr, 100) // ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° массива ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŽ
	fmt.Println(arr) // 101 102 103
}

Блайсы

Блайсы Π² Go

Блайс – это Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½Π°Ρ рСализация массива, которая ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ динамичСскоС ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°. Π’ исходном ΠΊΠΎΠ΄Π΅ Go ΠΎΠ½ прСдставляСт собой структуру с трСмя полями:

type slice struct {
	array unsafe.Pointer // ссылка Π½Π° массив
	len   int // Π΄Π»ΠΈΠ½Π°
	cap   int // Π΅ΠΌΠΊΠΎΡΡ‚ΡŒ
}

Из описания структуры ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ слайс Π½Π΅ Ρ…Ρ€Π°Π½ΠΈΡ‚ Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π΄Π°Π½Π½Ρ‹Ρ…, Π° всСго лишь описываСт Ρ‡Π°ΡΡ‚ΡŒ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ массива, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ссылаСтся.

Π”Π»ΠΈΠ½Π° слайса (len) – это количСство элСмСнтов, содСрТащихся Π² Π½Π΅ΠΌ.

Π•ΠΌΠΊΠΎΡΡ‚ΡŒ слайса (cap) – это количСство элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ сохранСны Π² слайсС Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Π°, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ Π΅Π³ΠΎ пСрСраспрСдСлСниС. ΠŸΡ€ΠΈ этом Π΅ΠΌΠΊΠΎΡΡ‚ΡŒ Π΄ΠΎΠ»ΠΆΠ½Π° Π±Ρ‹Ρ‚ΡŒ строго большС Π΄Π»ΠΈΠ½Ρ‹, ΠΈΠ½Π°Ρ‡Π΅ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ ошибка компиляции.

Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ слайс ΠΌΠΎΠΆΠ½ΠΎ нСсколькими способами:

  • Π‘ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΊΠ»ΡŽΡ‡Π΅Π²ΠΎΠ³ΠΎ слова var создаСтся nil-слайс:
var s1 []int
  • ΠšΠΎΡ€ΠΎΡ‚ΠΊΠΎΠ΅ объявлСниС:
s2 := []string{"a", "b"}
  • Π‘ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ make. Π’ Ρ‚Π°ΠΊΠΎΠΌ случаС Π΅ΠΌΠΊΠΎΡΡ‚ΡŒ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½Π° Π·Π°Π΄Π°Π½Π½ΠΎΠΉ Π΄Π»ΠΈΠ½Π΅:
s3 := make([]int, 3) // Π°Π½Π°Π»ΠΎΠ³ []int{0, 0, 0}
  • Π‘ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ΠΌ Ρ‚ΠΈΠΏΠ° Π΄Π°Π½Π½Ρ‹Ρ…, Ρ€Π°Π·ΠΌΠ΅Ρ€Π° ΠΈ ёмкости Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ make:
s4 := make([]int, 3, 5) // Π°Π½Π°Π»ΠΎΠ³ new([5]int)[:3]
  • Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ слайса ΠΈΠ· массива:
arr := [2]bool{true, false}
s5 := arr[:] // срСз ΠΏΠΎ массиву
  • Π‘ΠΎΠ·Π΄Π°Ρ‚ΡŒ n-ΠΌΠ΅Ρ€Π½Ρ‹ΠΉ слайс ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ добавлСния ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠΉ Π² Ρ†ΠΈΠΊΠ»Π΅ for:
slice2D := make([][]int, 3)
for i := range slice2D {
	slice2D[i] = make([]int, 3)
	slice2D[i][i] = 1
}
fmt.Println(slice2D) // [[1 0 0] [0 1 0] [0 0 1]]

Π‘Ρ€Π΅Π·

Π‘Ρ€Π΅Π· прСдставляСт собой слайс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ссылаСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° Π·Π°Π΄Π°Π½Π½ΡƒΡŽ Ρ‡Π°ΡΡ‚ΡŒ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ массива ΠΈΠ»ΠΈ слайса ΠΈ создаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ указания Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΈ ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠ³ΠΎ индСкса Π² ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π½Ρ‹Ρ… скобках:

slc := []int{1, 2, 3, 4, 5}
part := slc[0:2] // слайс []int{1, 2}

Блайс ΠΈ срСз часто ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΡŽΡ‚ Π² ΠΎΠ΄Π½ΠΎ понятиС ΠΈ ΠΏΠΎΠ΄Ρ€Π°Π·ΡƒΠΌΠ΅Π²Π°ΡŽΡ‚ ΠΏΠΎΠ΄ Π½ΠΈΠΌ структуру со ссылкой Π½Π° массив, Π΄Π»ΠΈΠ½ΠΎΠΉ ΠΈ Π΅ΠΌΠΊΠΎΡΡ‚ΡŒΡŽ.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ ΠΏΡƒΡ‚Π°Π½ΠΈΡ†Ρ‹, Π² Π΄Π°Π½Π½ΠΎΠΌ пособии Π±ΡƒΠ΄Π΅ΠΌ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ слайсом Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½Π½ΡƒΡŽ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ массива, ΡΠΎΠ·Π΄Π°Π½Π½ΡƒΡŽ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· Ρ€Π°Π½Π΅Π΅ рассмотрСнных способов, Π° срСзом – Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Π°ΡΡ‚ΡŒ исходного массива ΠΈΠ»ΠΈ слайса, ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΡƒΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ конструкции [:].

ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ слайсов Π² Go

ΠŸΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ со слайсами ΠΈ срСзами стоит ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ хранят ссылку Π½Π° Π΄Π°Π½Π½Ρ‹Π΅, поэтому ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΠΈΡ… элСмСнтов ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ измСнСнию ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… элСмСнтов Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ массива ΠΈΠ»ΠΈ слайса.

ΠŸΡ€ΠΎΠ΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌ эту ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅:

func main() {
	first := []int{1, 2, 3}
	second := first // []int{1, 2, 3}
	third := first[0:2] // []int{1, 2}

	second[0] = 10
	third[1] = 20
	fmt.Println(first, second, third)
	// Π’Ρ‹Π²ΠΎΠ΄:
	// [10 20 3] [10 20 3] [10 20]

	second = append(second, 60) // Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ second Π½Π΅ ссылаСтся Π½Π° first
	second[0] = 30
	fmt.Println(first, second, third)
	// Π’Ρ‹Π²ΠΎΠ΄:
	// [10 20 3] [30 20 3 60] [10 20]
}

Π’ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Π²Ρ‹Π²ΠΎΠ΄Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ измСнСния Π² слайсах second ΠΈ third ΠΊΠΎΡΠ½ΡƒΠ»ΠΈΡΡŒ Ρ‚Π°ΠΊΠΆΠ΅ слайса first. ΠŸΡ€ΠΈ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠΈ числа 60 Π² слайс second ΠΎΠ½ пСрСаллоцировался ΠΈ Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ пСрСстал ΡΡΡ‹Π»Π°Ρ‚ΡŒΡΡ Π½Π° first, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ хранится ΠΏΠΎ Π½ΠΎΠ²ΠΎΠΌΡƒ адрСсу. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π΅Π³ΠΎ Π½ΡƒΠ»Π΅Π²ΠΎΠ³ΠΎ элСмСнта Π½Π΅ коснСтся слайсов first ΠΈ third, Ρ‡Ρ‚ΠΎ Π²ΠΈΠ΄Π½ΠΎ Π²ΠΎ Π²Ρ‚ΠΎΡ€ΠΎΠΌ Π²Ρ‹Π²ΠΎΠ΄Π΅.

ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‡Π° слайса Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ

НСсмотря Π½Π° Ρ‚ΠΎ Ρ‡Ρ‚ΠΎ слайс содСрТит ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, ΠΎΠ½ Π½Π° самом Π΄Π΅Π»Π΅ являСтся ΠΈΠΌΠ΅Π½Π½ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ структуры, содСрТащСй ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ источник Π΄Π°Π½Π½Ρ‹Ρ….

Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€, наглядно Π΄Π΅ΠΌΠΎΠ½ΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΠΉ эту ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΡŒ. ΠŸΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ слайс nums Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π±Π΅Π· Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ³ΠΎ значСния doubleNumbers, которая ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ Π΅Π³ΠΎ элСмСнты Π΄Π²ΠΎΠ΅ ΠΈ попытаСтся ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄Π»ΠΈΠ½Ρƒ Π½Π° 2.

func doubleNumbers(slc []int) {
	for i := range slc {
		slc[i] *= 2
	}
	slc = slc[0 : len(slc)-2]
}

func main() {
	nums := []int{1, 2, 3, 4}
	doubleNumbers(nums)
	fmt.Println(nums, len(nums), cap(nums)) // [2 4 6 8] 4 4
}

Как Π½Π΅Ρ‚Ρ€ΡƒΠ΄Π½ΠΎ Π·Π°ΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ, элСмСнты nums Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ»ΠΈΡΡŒ Π² Π΄Π²Π° Ρ€Π°Π·Π°, Π° Π²ΠΎΡ‚ Π΄Π»ΠΈΠ½Π° ΠΎΡΡ‚Π°Π»Π°ΡΡŒ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΠΎΠΉ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ doubleNumbers ΠΈ присвоим Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π΅Ρ‘ выполнСния ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ newNums:

func doubleNumbers(slc []int) []int {
	for i := range slc {
		slc[i] *= 2
	}
	slc = slc[0 : len(slc)-2]
	return slc
}

func main() {
	nums := []int{1, 2, 3, 4}
	newNums := doubleNumbers(nums)

	fmt.Println(nums, newNums)
	fmt.Println("len nums:", len(nums), "cap nums:", cap(nums))
	fmt.Println("len newNums:", len(newNums), "cap newNums:", cap(newNums))
	// [2 4 6 8] [2 4]
	// len nums: 4, cap nums: 4
	// len newNums: 2, cap newNums: 4
}

Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС слайс nums Π½Π΅ измСняСтся, Π½ΠΎ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ содСрТит Π½ΠΎΠ²ΡƒΡŽ Π΄Π»ΠΈΠ½Ρƒ, которая сохранится Π² newNums.

Π”Π»ΠΈΠ½Π° слайса nums ΠΎΡΡ‚Π°Π»Π°ΡΡŒ Π½Π΅ΠΈΠ·ΠΌΠ΅Π½Π½ΠΎΠΉ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅Π΄Π°Π»Π°ΡΡŒ Π΅Ρ‘ копия, Π° Π½Π΅ ΠΎΡ€ΠΈΠ³ΠΈΠ½Π°Π». Если Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΄Π»ΠΈΠ½Ρƒ, Π½ΡƒΠΆΠ½ΠΎ явно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΠΏΡ€ΠΈΡΠ²ΠΎΠΈΡ‚ΡŒ Π΅Π³ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅, ΠΊΠ°ΠΊ это Π±Ρ‹Π»ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π² послСднСм ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅.

Append

Для добавлСния элСмСнтов Π² слайс ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ функция append со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ сигнатурой:

func append(s []T, vs ...T) []T

Она ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΎΠ² слайс ΠΈ значСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π² Π½Π΅Π³ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ. Π’ ΠΊΠΎΠ΄Π΅ Π½ΠΈΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Π½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΅Ρ‘ примСнСния:

arr := []int{1, 2, 3}
arr = append(arr, 4)
arr = append(arr, 5, 6)
fmt.Println(arr) // [1 2 3 4 5 6]

arr = append(arr, "string") // ошибка

Π’ Go допускаСтся Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ слайса Π² Π΄Ρ€ΡƒΠ³ΠΎΠΉ. Π­Ρ‚ΠΎ дСлаСтся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

slc1 := []int{10, 11, 12}
slc2 := []int{13, 14, 15}
slc1 = append(slc1, slc2...)
fmt.Println(slc1) // [10 11 12 13 14 15]

slc3 := append([]int(nil), slc2...) // созданиС копии slc2
slc2 = append(slc2, slc2...) // Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ slc2 Π² ΠΊΠΎΠ½Π΅Ρ† slc2
fmt.Println(slc2, slc3) // [13 14 15 13 14 15] [13 14 15]

Π’ΠΎ врСмя выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ функция append ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ€Π΅ΡˆΠ°Π΅Ρ‚, Π½ΡƒΠΆΠ½ΠΎ Π»ΠΈ ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ слайс. Π­Ρ‚ΠΎ происходит, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΡ€ΠΈ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½ΠΈΠΈ ΠΈΠΌΠ΅ΡŽΡ‰Π΅ΠΉΡΡ Смкости:

func main() {
	var slc = make([]int, 5)

	fmt.Printf("old address: %p\\n", slc)            // исходный адрСс
	fmt.Println("len:", len(slc), "cap:", cap(slc)) // 5 5

	slc = append(slc, 1)

	fmt.Printf("new address: %p\\n", slc)            // Π½ΠΎΠ²Ρ‹ΠΉ адрСс
	fmt.Println("len:", len(slc), "cap:", cap(slc)) // 6 10
}

Π’ ΠΊΠΎΠ΄Π΅ Π²Ρ‹ΡˆΠ΅ ΠΏΡ€ΠΈ Π²Ρ‹Π·ΠΎΠ²Π΅ append Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€Π΅Π²Ρ‹ΡˆΠ΅Π½Π° Π΅ΠΌΠΊΠΎΡΡ‚ΡŒ слайса slc, Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Π΅Ρ‘ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΡŽ Π²Π΄Π²ΠΎΠ΅ ΠΈ измСнСнию адрСса slc Π½Π° Π½ΠΎΠ²Ρ‹ΠΉ.

Ѐункция append Π½Π°ΠΏΡ€ΡΠΌΡƒΡŽ влияСт Π½Π° использованиС памяти Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅, поэтому для избСТания Π»ΠΈΡˆΠ½ΠΈΡ… Π°Π»Π»ΠΎΠΊΠ°Ρ†ΠΈΠΉ ΠΈ Π½Π΅Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ копирования, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° Π΅ΠΌΠΊΠΎΡΡ‚ΡŒΡŽ созданных слайсов.

Copy

Ѐункция Copy Π² Go

ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ слайсов производится с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ copy со ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ сигнатурой:

func copy(dst, src []Type) int

Она ΠΊΠΎΠΏΠΈΡ€ΡƒΠ΅Ρ‚ элСмСнты ΠΈΠ· исходного слайса Π² Ρ†Π΅Π»Π΅Π²ΠΎΠΉ ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ количСство скопированных элСмСнтов, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡŒΠ½Ρ‹ΠΌ ΠΈΠ· len(dst) ΠΈ len(src).

Рассмотрим нСсколько классичСских ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² использования copy:

  • ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ слайса большСго Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π² слайс с мСньшим:
slc := []int{1, 2}
n3 := copy(slc, []int{3, 4, 5})
fmt.Println(n3, slc) // 2 [3, 4]
  • ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ слайса мСньшСго Ρ€Π°Π·ΠΌΠ΅Ρ€Π° Π² слайс с большим:
slc := []int{1, 2, 3, 4}
n3 := copy(slc, []int{5, 6})
fmt.Println(n3, slc) // 2 [5, 6, 3, 4]
  • ΠšΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ слайса Π² самого сСбя:
slc := []int{1, 2, 3, 4}
n2 := copy(slc, slc[2:])
fmt.Println(n2, slc) // 2 [3 4 3 4]
  • ΠžΡΠΎΠ±Ρ‹ΠΉ случай – ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π±Π°ΠΉΡ‚ΠΎΠ² строки Π² слайс Π±Π°ΠΉΡ‚ΠΎΠ².
s := "example"
bytes := make([]byte, 3)
copy(bytes, s)
fmt.Println(bytes, string(bytes)) // [101 120 97] exa

copy(bytes, s[3:])
fmt.Println(bytes, string(bytes)) // [109 112 108] mpl

ΠŸΠ°ΠΊΠ΅Ρ‚ slices

Π’ вСрсии 1.21 Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ Go Π΄ΠΎΠ±Π°Π²ΠΈΠ»ΠΈ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠ°ΠΊΠ΅Ρ‚ slices, ΠΎΠ±Π»Π΅Π³Ρ‡Π°ΡŽΡ‰ΠΈΠΉ Ρ€Π°Π±ΠΎΡ‚Ρƒ со слайсами. Он позволяСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ для выполнСния Π±Π°Π·ΠΎΠ²Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ со слайсами, Ρ‡Ρ‚ΠΎ Π² Ρ€Π°Π·Ρ‹ ΡƒΠΏΡ€ΠΎΡ‰Π°Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρƒ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡ‡ΡƒΠ²ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ Ρ€Π°Π·Π½ΠΈΡ†Ρƒ, обратимся ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ ΠΊΠΎΠ΄Π° для поиска максимального значСния Π² слайсС Π΄ΠΎ ΠΈ послС ввСдСния ΠΏΠ°ΠΊΠ΅Ρ‚Π° slices:

// Π΄ΠΎ ΠΏΠ°ΠΊΠ΅Ρ‚Π° slices:
slc := []int{5, 9, 1, 100}
max := slc[0]
for _, val := range slc {
	if val > max {
		max = val
	}
}

// ΠΏΠ°ΠΊΠ΅Ρ‚ slices:
max := slices.Max(slc)

Π’Π΅ΠΏΠ΅Ρ€ΡŒ рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ практичСского примСнСния Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΈΠ· ΠΏΠ°ΠΊΠ΅Ρ‚Π° slices:

  • Π‘ΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²ΠΊΠ° слайса – slices.Sort:
slc := []int{4, 3, 5, 2, 6, 1}
slices.Sort(slc) // [1 2 3 4 5 6]
  • Π‘Ρ€Π°Π²Π½Π΅Π½ΠΈΠ΅ слайсов – slices.Compare:
slc1 := []int{1, 2, 7, 3}
slc2 := []int{2, 3, 1, 7}
fmt.Println(slices.Compare(slc1, slc2)) // -1
  • Поиск элСмСнта Π² слайсС – slices.Contains:
slc := []int{1, 2, 7, 3}
	fmt.Println(slices.Contains(slc, 1))
	fmt.Println(slices.Contains(slc, 4))
  • Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ элСмСнтов Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ [i:j] ΠΈΠ· слайса – slices.Delete:
slc := []int{1, 2, 7, 3}
slc = slices.Delete(slc, 0, 2)
fmt.Println(slc) // [7, 3]
  • Вставка элСмСнтов начиная с ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ индСкса – slices.Insert:
letters := []string{"alpha", "delta"}
letters = slices.Insert(letters, 1, "beta", "gamma")
fmt.Println(letters)

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ всС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠ°ΠΊΠ΅Ρ‚Π° slices ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ ΠΈΡ… использования ΠΌΠΎΠΆΠ½ΠΎ Π½Π° ΠΎΡ„ΠΈΡ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠΌ сайтС go.

Π—Π°Π΄Π°Ρ‡ΠΈ

Π”Π°Π²Π°ΠΉΡ‚Π΅ Ρ€Π΅ΡˆΠΈΠΌ нСсколько классичСских Π·Π°Π΄Π°Ρ‡ Π½Π° массивы ΠΈ слайсы для оттачивания Π½Π°Π²Ρ‹ΠΊΠΎΠ² программирования ΠΈ закрСплСния ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π° ΡΡ‚Π°Ρ‚ΡŒΠΈ. Для ΠΈΡ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ достаточно ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚ΡŒ ΠΈΠ·ΡƒΡ‡Π΅Π½Π½Ρ‹Π΅ Π² этом ΡƒΡ€ΠΎΠΊΠ΅ конструкции, ΠΏΡ€ΠΈ этом Π½Π΅ рСкомСндуСтся ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ сторонниС ΠΏΠ°ΠΊΠ΅Ρ‚Ρ‹, Ρ‚Π°ΠΊΠΈΡ… ΠΊΠ°ΠΊ slices, math ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΠ΅.

Π‘Π°ΠΌΡ‹ΠΉ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ Π΄ΠΎΠΌ

Π—Π°Π΄Π°Ρ‡Π° Β«Π‘Π°ΠΌΡ‹ΠΉ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ Π΄ΠΎΠΌΒ»

На Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΡƒΠ»ΠΈΡ†Π΅ Π² ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ»ΡŒΠ½ΠΎΠΌ порядкС стоят n Π΄ΠΎΠΌΠΎΠ². ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ Π΄ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ΄Π½ΠΎΠ·Π½Π°Ρ‡Π½ΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ€Π° ΠΈ индСкса располоТСния ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½Π°Ρ‡Π°Π»Π° ΡƒΠ»ΠΈΡ†Ρ‹ (ΠΎΠ½Π° начинаСтся слСва). ΠŸΡ€ΠΈ этом Π½ΠΎΠΌΠ΅Ρ€Π° Π΄ΠΎΠΌΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΡΡ‚ΡŒΡΡ. НазовСм Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ Π΄ΠΎΠΌ, ΠΈΠΌΠ΅ΡŽΡ‰ΠΈΠΉ наибольший Π½ΠΎΠΌΠ΅Ρ€ ΠΈ Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‰ΠΈΠΉΡΡ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ Π±Π»ΠΈΠ·ΠΊΠΎ ΠΊ Π½Π°Ρ‡Π°Π»Ρƒ ΡƒΠ»ΠΈΡ†Ρ‹. Π’Π°ΡˆΠ° Π·Π°Π΄Π°Ρ‡Π° β€” вывСсти Π½ΠΎΠΌΠ΅Ρ€ ΠΈ индСкс Ρ‚Π°ΠΊΠΎΠ³ΠΎ Π΄ΠΎΠΌΠ°.

Π’Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅: Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΉ строкС подаСтся количСство чисСл – Π½Π°Ρ‚ΡƒΡ€Π°Π»ΡŒΠ½ΠΎΠ΅ число n (n < 1000), Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ строкС Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ±Π΅Π» ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ цСлочислСнныС Π½ΠΎΠΌΠ΅Ρ€Π° Π΄ΠΎΠΌΠΎΠ² Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ ΠΎΡ‚ -10^4 Π΄ΠΎ 10^4.

Π’Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅: Π΄Π²Π° числа – Π½ΠΎΠΌΠ΅Ρ€ ΠΈ индСкс Ρ…ΠΎΡ€ΠΎΡˆΠ΅Π³ΠΎ Π΄ΠΎΠΌΠ°.

РСшСниС: Π·Π°Π΄Π°Ρ‡Π° Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π½Π°Ρ…ΠΎΠΆΠ΄Π΅Π½ΠΈΠΈ значСния ΠΈ индСкса максимального числа массива.

func main() {
	var n int
	fmt.Scan(&n)
	nums := make([]int, n)
	for i := range nums {
		fmt.Scan(&nums[i])
	}

	var maxValue = -10001
	var maxIndex = -10001
	for i := range nums {
		if nums[i] > maxValue {
			maxValue = nums[i]
			maxIndex = i
		}
	}
	fmt.Println(maxValue, maxIndex)
}

Π“ΠΎΡˆΠ° ΠΈΡ‰Π΅Ρ‚ Ρ€Π΅Π΄ΠΊΠΈΠ΅ числа

Π“ΠΎΡˆΠ° Π²ΡΠ΅Ρ€ΡŒΡ‘Π· увлСкся ΠΌΠ°Ρ‚Π΅ΠΌΠ°Ρ‚ΠΈΠΊΠΎΠΉ ΠΈ поставил сСбС Ρ‚Π°ΠΊΡƒΡŽ Π·Π°Π΄Π°Ρ‡Ρƒ: Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π½Π° доскС n Ρ†Π΅Π»Ρ‹Ρ… чисСл ΠΈ Π½Π°ΠΉΡ‚ΠΈ срСди Π½ΠΈΡ… самыС Ρ€Π΅Π΄ΠΊΠΈΠ΅, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅, Ρ‡Ρ‚ΠΎ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·. Π’Π°ΡˆΠ° Π·Π°Π΄Π°Ρ‡Π° ΠΏΠΎΠΌΠΎΡ‡ΡŒ Π“ΠΎΡˆΠ΅ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ свои вычислСния, написав ΠΊΠΎΠ΄ для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой интСрСсной Π·Π°Π΄Π°Ρ‡ΠΈ.

Π’Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅: Π½Π° ΠΏΠ΅Ρ€Π²ΠΎΠΉ строкС подаСтся количСство чисСл – Π½Π°Ρ‚ΡƒΡ€Π°Π»ΡŒΠ½ΠΎΠ΅ число n (n < 10^6), Π½Π° Π²Ρ‚ΠΎΡ€ΠΎΠΉ строкС Ρ‡Π΅Ρ€Π΅Π· ΠΏΡ€ΠΎΠ±Π΅Π» ΠΏΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»ΡΡŽΡ‚ΡΡ Ρ†Π΅Π»Ρ‹Π΅ числа.

Π’Ρ‹Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅: числа, Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‰ΠΈΠ΅ΡΡ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ€ΠΎΠ²Π½ΠΎ ΠΎΠ΄ΠΈΠ½ Ρ€Π°Π·.

РСшСниС:

func main() {
	var n int
	fmt.Scan(&n)
	nums := make([]int, n)
	for i := range nums {
		fmt.Scan(&nums[i])
	}

	var cnt int // счСтчик вхоТдСния Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² массив
	for i := range nums {
		cnt = 0 // ΠΊΠ°ΠΆΠ΄ΡƒΡŽ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΡŽ обнуляСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика
		for j := range nums {
			// Ссли Π΄Π²Π° числа с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ индСксами совпали
			if nums[i] == nums[j] && i != j {
				cnt++ // ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика
			}
		}
		// Ссли счСтчик Ρ€Π°Π²Π΅Π½ Π½ΡƒΠ»ΡŽ, это Π·Π½Π°Ρ‡ΠΈΡ‚, Ρ‡Ρ‚ΠΎ Π² 
		// Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ Π½Π΅ Π±Ρ‹Π»ΠΎ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡŽΡ‰ΠΈΡ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ
		if cnt == 0 {
			fmt.Println(nums[i])
		}
	}
}

ΠŸΠ΅Ρ€Π΅ΡΡ‚Π°Π½ΠΎΠ²ΠΊΠ° сосСдСй

ΠΠ°ΠΏΠΈΡˆΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ shiftNeighbour(nums []int) для пСрСстановки сосСдних элСмСнтов слайса. Для Π½Π΅Ρ‡Π΅Ρ‚Π½ΠΎΠ³ΠΎ количСства элСмСнтов послСдний ΠΈΠ· Π½ΠΈΡ… остаСтся Π±Π΅Π· измСнСния.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ:

nums1 := []int{1, 2, 3, 4}
shiftNeighbour(nums1)
fmt.Println(nums1) // [2 1 4 3]

nums2 := []int{9, 8, 10}
shiftNeighbour(nums2)
fmt.Println(nums2) // [8 9 10]

РСшСниС:

func shiftNeighbour(nums []int) {
	for i := 1; i < len(nums); i += 2 {
		tmp := nums[i]
		nums[i] = nums[i-1]
		nums[i-1] = tmp
	}
}

ЦикличСский сдвиг слайса*

Π Π΅Π°Π»ΠΈΠ·ΡƒΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ sliceShift(nums []int, shift int) []int для цикличСского сдвига слайса Π½Π° shift элСмСнтов Π²ΠΏΡ€Π°Π²ΠΎ, Ссли shift > 0, ΠΈ Π²Π»Π΅Π²ΠΎ, Ссли shift < 0.

Подсказка: для заполнСния Π½ΠΎΠ²ΠΎΠ³ΠΎ слайса ΠΊΠΎΠΏΠΈΡ€ΡƒΠΉΡ‚Π΅ Π² Π½Π΅Π³ΠΎ Ρ‡Π°ΡΡ‚ΡŒ исходного с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ copy().

РСшСниС: для Π½Π°Ρ‡Π°Π»Π° ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅ΠΌ сдвиг ΠΊ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΠ΅. Если shift > 0, Ρ‚ΠΎ достаточно Π²Π·ΡΡ‚ΡŒ остаток ΠΎΡ‚ дСлСния сдвига Π½Π° len(nums). Π’ случаС shift < 0 Π·Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ сдвиг Π²Π»Π΅Π²ΠΎ Ρ€Π°Π²Π΅Π½ сдвигу Π²ΠΏΡ€Π°Π²ΠΎ Π½Π° len(nums) + shift, ΠΈ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ΅ΠΌ Π΅Π³ΠΎ ΠΊ Π½ΡƒΠΆΠ½ΠΎΠΌΡƒ Π²ΠΈΠ΄Ρƒ. Π”Π°Π»Π΅Π΅ создадим Π½ΠΎΠ²Ρ‹ΠΉ слайс ΠΈ скопируСм Ρ‚ΡƒΠ΄Π° элСмСнты исходного, учитывая индСксы:

func sliceShift(nums []int, shift int) []int {
	ln := len(nums)
	shift %= ln
	if shift < 0 { // ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ сдвига ΠΊ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΠ΅
		shift = -shift
		shift %= ln
		shift = ln - shift
	}
	res := make([]int, ln)
	copy(res[shift:], nums[:ln-shift])
	copy(res[:shift], nums[ln-shift:])
	return res
}

ΠŸΠΎΠ΄Π²Π΅Π΄Ρ‘ΠΌ ΠΈΡ‚ΠΎΠ³ΠΈ

ΠœΠ°ΡΡΠΈΠ²Ρ‹ ΠΈ слайсы ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°ΠΌ ΠΌΠΎΡ‰Π½Ρ‹Π΅ инструмСнты для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΡˆΠΈΡ€ΠΎΠΊΠΎΠ³ΠΎ спСктра Π·Π°Π΄Π°Ρ‡. ΠœΠ°ΡΡΠΈΠ²Ρ‹ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ для хранСния статичСской ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ, Π² Ρ‚ΠΎ врСмя ΠΊΠ°ΠΊ слайсы ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‚ Π³ΠΈΠ±ΠΊΠΎΡΡ‚ΡŒ ΠΈ удобство Ρ€Π°Π±ΠΎΡ‚Ρ‹ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°ΠΌΠΈ Π΄Π°Π½Π½Ρ‹Ρ….

Π’ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠ΅ Ρ†ΠΈΠΊΠ»Π° погрузимся Π² ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ строк, Π±Π°ΠΉΡ‚ΠΎΠ², Ρ€ΡƒΠ½, Ρ€Π°Π·Π±Π΅Ρ€Π΅ΠΌ ΠΈΡ… особСнности ΠΈ познакомимся с Ρ…Π΅Ρˆ-Ρ‚Π°Π±Π»ΠΈΡ†Π°ΠΌΠΈ.

***

Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅ самоучитСля

  1. ΠžΡΠΎΠ±Π΅Π½Π½ΠΎΡΡ‚ΠΈ ΠΈ сфСра примСнСния Go, установка, настройка
  2. РСсурсы для изучСния Go с нуля
  3. ΠžΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΡ ΠΊΠΎΠ΄Π°. ΠŸΠ°ΠΊΠ΅Ρ‚Ρ‹, ΠΈΠΌΠΏΠΎΡ€Ρ‚Ρ‹, ΠΌΠΎΠ΄ΡƒΠ»ΠΈ. Π’Π²ΠΎΠ΄-Π²Ρ‹Π²ΠΎΠ΄ тСкста.
  4. ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅. Π’ΠΈΠΏΡ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈ ΠΈΡ… прСобразования. ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹
  5. УсловныС конструкции if-else ΠΈ switch-case. Π¦ΠΈΠΊΠ» for. Π’Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ ΠΈ бСсконСчныС Ρ†ΠΈΠΊΠ»Ρ‹
  6. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹. ΠžΠ±Π»Π°ΡΡ‚ΠΈ видимости. РСкурсия. Defer
  7. ΠœΠ°ΡΡΠΈΠ²Ρ‹ ΠΈ слайсы. Append ΠΈ сopy. ΠŸΠ°ΠΊΠ΅Ρ‚ slices
  8. Π‘Ρ‚Ρ€ΠΎΠΊΠΈ, Ρ€ΡƒΠ½Ρ‹, Π±Π°ΠΉΡ‚Ρ‹. ΠŸΠ°ΠΊΠ΅Ρ‚ strings. Π₯Сш-Ρ‚Π°Π±Π»ΠΈΡ†Π° (map)
  9. Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Ρ‹ ΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹. Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡ‹. Π£ΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ. ΠžΡΠ½ΠΎΠ²Ρ‹ ООП
  10. НаслСдованиС, абстракция, ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„ΠΈΠ·ΠΌ, инкапсуляция
  11. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ошибок. Паника. ВосстановлСниС. Π›ΠΎΠ³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•

Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
04 октября 2018

ΠŸΠΎΠΌΠ½ΠΈΡ‚ΡŒ всС: дСлимся Π»ΡƒΡ‡ΡˆΠ΅ΠΉ ΡˆΠΏΠ°Ρ€Π³Π°Π»ΠΊΠΎΠΉ ΠΏΠΎ Python

ΠœΡ‹ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΈΠ»ΠΈ ΠΎΡ‡Π΅Π½ΡŒ Π·Π°Π½ΠΈΠΌΠ°Ρ‚Π΅Π»ΡŒΠ½ΡƒΡŽ ΠΊΠΎΠ»Π»Π΅ΠΊΡ†ΠΈΡŽ, которая ΠΏΠΎ ΠΏΡ€Π°Π²Ρƒ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°Π·Ρ‹Π²Π°...
Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° программиста
22 апрСля 2017

Английский язык для IT-спСциалистов

ВсСм людям, Ρ‚Π°ΠΊ ΠΈΠ»ΠΈ ΠΈΠ½Π°Ρ‡Π΅ связанным с IT сфСрой, прСкрасно извСстно, Ρ‡Ρ‚ΠΎ Ρ€Π°...
admin
29 января 2017

Π˜Π·ΡƒΡ‡Π°Π΅ΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹: ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Π΅ ΠΊΠ½ΠΈΠ³ΠΈ, Π²Π΅Π±-сайты, ΠΎΠ½Π»Π°ΠΉΠ½-курсы ΠΈ Π²ΠΈΠ΄Π΅ΠΎΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹

Π’ этой ΠΏΠΎΠ΄Π±ΠΎΡ€ΠΊΠ΅ прСдставлСн список ΠΊΠ½ΠΈΠ³, Π²Π΅Π±-сайтов ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½-курсов, Π΄Π°ΡŽΡ‰ΠΈΡ…...