Задать вопрос
@bozedai

Можно ли в Golang изменить длину среза напрямую?

Проблема такая: в функцию передается срез

func foo(bar []int){
    // Как изменить length у среза?
}
input := []int{1, 2, 3}
foo(input)
fmt.Println(len(input)) // Например: 2


И нужно внутри функции изменить длину срез, не создавая новый, чтобы по старому указателю все было доступно.

Так вот не работает
*&bar = bar[:2]
  • Вопрос задан
  • 826 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
EvgenyMamonov
@EvgenyMamonov Куратор тега Go
Senior software developer, system architect
Можно попробовать сделать через reflect, например так
package main

import (
    "fmt"
    "reflect"
)

func modify(input *[]int, newLen int) {
    val := reflect.Indirect(reflect.ValueOf(input))
    val.SetLen(newLen)
}

func main() {
    input := []int{1, 2, 3}

    fmt.Printf("Before: %p, value: %v\n", &input, input)

    modify(&input, len(input) - 1)

    fmt.Printf("After: %p, value: %v\n", &input, input)
}

Вывод:
Before: 0xc00000c060, value: [1 2 3]
After: 0xc00000c060, value: [1 2]
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@Klars
Еще вариант
package main

import (
	"fmt"
)

func squeeze(sl *[]int, splitter int) {
	s := *sl
	s = s[:splitter]
	*sl = s
}

func main() {
	sl := []int{1, 2, 3, 4, 5, 6}
	fmt.Println(len(sl), cap(sl), sl)
	fmt.Printf("%p\n\n", &sl)

	squeeze(&sl, 4)

	fmt.Println(len(sl), cap(sl), sl)
	fmt.Printf("%p", &sl)
}


output:
6 6 [1 2 3 4 5 6]
0xc00000c0a0

4 6 [1 2 3 4]
0xc00000c0a0
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы