передача ссылок без обновления байтового массива - PullRequest
0 голосов
/ 25 февраля 2020

Я пытаюсь выяснить манипулирование файлами в памяти для проекта Lambda, над которым я работаю. Эта фиктивная программа иллюстрирует мое незнание:

package main

import (
    "bytes"
    "fmt"
    "log"
)

func Append(input *[]byte, appendee string) (err error)  {
   buf := bytes.NewBuffer(*input)
   if _, err := buf.WriteString(appendee); err != nil {
       log.Println(err)
   } 

   return err
}


func main() {
   test := "this is a test\nThis test is short\nBut longer tests would work also\n"

   b := []byte(test)

   fmt.Println(b)

   err := Append(&b, "This is an appended line")

   if err != nil {
           fmt.Println("oops")
   }

   fmt.Println(b)
}

Я надеюсь, что если передать ссылку на байтовый массив в строке, которая вызывает Append, эта функция может манипулировать той же структурой данных, что и main, и затем печать будет содержать добавленную строку. Но это не так. Вот исполнение:

✗ go run test.go
[116 104 105 115 32 105 115 32 97 32 116 101 115 116 10 84 104 105 115 32 116 101 115 116 32 
105 115 32 115 104 111 114 116 10 66 117 116 32 108 111 110 103 101 114 32 116 101 115 116 
115 32 119 111 117 108 100 32 119 111 114 107 32 97 108 115 111 10]
[116 104 105 115 32 105 115 32 97 32 116 101 115 116 10 84 104 105 115 32 116 101 115 116 32 
105 115 32 115 104 111 114 116 10 66 117 116 32 108 111 110 103 101 114 32 116 101 115 116 
115 32 119 111 117 108 100 32 119 111 114 107 32 97 108 115 111 10]

Чего мне не хватает?

Ответы [ 2 ]

1 голос
/ 25 февраля 2020

Вам не хватает строки:

package main

import (
    "bytes"
    "fmt"
    "log"
)

// Using your function
func Append(input *[]byte, appendee string) error {
    buf := bytes.NewBuffer(*input)
    if _, err := buf.WriteString(appendee); err != nil {
        log.Println(err)
        return err
    }
    // You are missing this one
    *input = buf.Bytes()
    return nil
}

// Using another approach
func Append2(input *[]byte, a string) {
    sb := []byte(a)
    *input = append(*input, sb...)
}

// As pointed by @cerise-limón, is no necessary to perform type conversion from string to byte during the append
func Append3(input *[]byte, a string) {
    *input = append(*input, a...)
}

func main() {
    var (
        test     string = "this is a test\nThis test is short\nBut longer tests would work also\n"
        toAppend string = "This is an appended line\n"
    )
    b := []byte(test)
    fmt.Println(b)
    if err := Append(&b, "1) "+toAppend); err != nil {
        fmt.Printf("oops: %s\n", err.Error())
    }
    fmt.Println(string(b))

    Append2(&b, "2) "+toAppend)
    fmt.Println(string(b))
    Append3(&b, "3) "+toAppend)
    fmt.Println(string(b))
}
1 голос
/ 25 февраля 2020

Вам не хватает *input = buf.Bytes() до return err в Append функции

func Append(input *[]byte, appendee string) (err error) {
    buf := bytes.NewBuffer(*input)
    if _, err := buf.WriteString(appendee); err != nil {
        log.Println(err)
    }
    *input = buf.Bytes()
    return err
}

Посмотрите на рабочий код на go детской площадке.

...