簡體   English   中英

將 int[] 傳遞給函數但函數返回空數組

[英]passing int[] to function but function returning empty array

我將一個字符串數組和一個空的整數數組傳入一個函數。 該函數的重點是將字符串數組的每個元素轉換為整數並將其存儲到整數數組中。 當我從函數本身打印整數數組時,一切都很好。 但是,當我嘗試在函數外部打印整數數組時,它會打印一個空數組。

employeeDataInt是整數數組, employeeDataString是字符串數組。

如果這是一個愚蠢的問題,我深表歉意,但我是新手。 謝謝

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
    "strconv"
    "strings"
)

func strToInt(employeeDataString []string, emplyoeeDataInt []int) []int {
    for _, i := range employeeDataString[2:] {
        j, err := strconv.Atoi(i)
        if err != nil {
            panic(err)
        }
        employeeDataInt = append(employeeDataInt, j)
        fmt.Println(employeeDataInt) //this prints out the appropriate array

    }
    return employeeDataInt
}

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter file name: ")
    fileName, err := reader.ReadString('\n')
    if err != nil {
        log.Fatalf("failed opening file: %s", err)
    }
    fileName = strings.TrimSuffix(fileName, "\n")

    file, err := os.Open(fileName)
    scanner := bufio.NewScanner(file)
    scanner.Split(bufio.ScanLines)
    var employeeLine []string

    for scanner.Scan() {
        employeeLine = append(employeeLine, scanner.Text())
    }

    file.Close()
    var employeeDataString = []int{}
    for _, employee := range employeeLine {
        employeeDataString := strings.Split(employee, " ")

        strToInt(employeeDataString, employeeDataInt)
        fmt.Println(playerData2) //this is outputting just `[]`

    }
}

您沒有獲取數組的值,因此您傳遞給函數的 Slice 可能會也可能不會正確更新。

strToInt(employeeDataString, employeeDataInt)
// should be
employeeDataInt = strToInt(employeeDataString, employeeDataInt)

在此期間,您永遠不會分配playerData2 所以fmt.Println(playerData2)總是[]

但除此之外,您在此處使用數組/切片還存在一些微妙的問題:

首先是SlicesArrays的區別:

Go 不允許您直接使用數組。 除非它們具有固定長度( [3]int{}[]int{1,2,3] ),否則您實際上不是在查看數組,而是在查看Slice[]int )。

切片只是一個指向數組的指針(連同它的容量和一些其他信息),它基本上允許 Go 安全地處理數組,因為您永遠不會增長現有數組(數組的大小在初始化時固定)。 所以你永遠不能追加到一個數組。

Go 給你附加到數組的錯覺是有一個大於所需的底層數組,並且Slice控制對該數組的訪問。 因此,如果底層數組的容量為 5 並且您已經在其中存儲了 3 個項目,則可以執行 2 次append操作,而無需分配新數組並將現有數組元素復制到新的內存位置。

因此,當您傳遞[]int您實際上是在傳遞一個數組指針(按值)。

這會導致代碼中的下一個問題: append的使用。 如上所述, append需要一個 Slice,查看底層數組以及實際剩余多少空間,然后添加到它分配一個新數組。 如果分配了新數組,則append返回指向新數組的切片。

所以調用:

foo := []{1,2,3}
append(foo, 4)
append(foo, 5)
append(foo, 6)
fmt.Print(foo) 
// => might return 1,2,3,4,5

您始終必須采用append的返回值,否則您仍有可能引用未附加新項目的“舊”切片。

因此,增長 Slice 或一般使用 Slices 的正確方法是記住: Slices 按值傳遞,因此始終使用 Slice 修改函數的返回值更新變量。

您的代碼中有幾個問題:

  • 您正在丟棄strToInt的返回值。
  • 您正在嘗試在main使用employeeDataInt但它在那里未定義(這應該導致編譯錯誤,而不是運行時問題)。
  • 您在main兩個不同范圍內( for循環內部和外部)聲明了兩次employeeDataString ,具有兩種不同的類型( []string[]int )。 外部作用域變量未使用,因此也應該導致編譯錯誤。
  • 您正在打印從未定義或使用過的playerData2 - 同樣,這應該導致編譯器錯誤,而不是不正確的行為。

鑒於代碼中存在編譯錯誤,您的帖子中缺少某些關鍵代碼,或者您沒有注意到/提及編譯錯誤。

main 中的正確代碼是:

var employeeDataInt []int  // Seems like you just have the wrong variable name here
for _, employee := range employeeLine {
    employeeDataString := strings.Split(employee, " ")

    // You're missing the assignment here
    employeeDataInt = strToInt(employeeDataString, employeeDataInt)
    fmt.Println(employeeDataInt) // This was referencing the wrong variable

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM