我正在将字符串数组和一个空整数数组传递给函数。该函数的重点是将字符串数组的每个元素转换为整数并将其存储到整数数组中。当我从函数内部打印整数数组时,一切都很好。但是,当我尝试在函数外部打印整数数组时,它将打印一个空数组。
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 `[]`
}
}
答案 0 :(得分:2)
您没有获取数组的值,因此传递给函数的Slice可能正确更新,也可能无法正确更新。
strToInt(employeeDataString, employeeDataInt)
// should be
employeeDataInt = strToInt(employeeDataString, employeeDataInt)
在此期间,您永远不会分配playerData2
。因此fmt.Println(playerData2)
将永远是[]
。
但是除此之外,在这里使用数组/切片还存在一些细微的问题:
首先Slices
and Arrays
之间的区别:
Go不允许您直接使用数组。
除非它们具有固定长度([3]int{}
或[]int{1,2,3]
),否则您实际上不是在看数组,而是在看Slice
([]int
)。
slice只是一个指向数组的指针(以及它的容量和其他信息),它实际上使Go可以安全地处理数组,因为您永远不会增长现有的数组(数组的大小在初始化时是固定的)。因此,您永远不能追加到数组。
Go所做的使您错觉到附加到数组的幻觉具有的数组要大于所需的基础数组,而Slice
控制对该数组的访问。因此,如果基础数组的容量为5,并且您已经在其中存储了3个项目,则可以执行2 append
个操作,而不必分配新的数组并将现有的数组元素复制到新的内存位置。
因此,当您传递[]int
时,实际上是在传递数组指针(按值)。
这将导致代码中的下一个难题:append
的使用。
如上所述,append
进行切片,查看基础数组以及实际剩余的空间,然后添加到或中,以分配新的数组。如果分配了新数组append
返回指向新数组的 new 切片。
所以打电话:
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 are passed by value,因此请始终保持使用Slice修改函数的返回值更新变量。
答案 1 :(得分:0)
您的代码中存在一些问题:
strToInt
的返回值。employeeDataInt
中使用main
,但是在此未定义(这会导致编译错误,而不是运行时问题)。employeeDataString
的两个不同范围(main
循环的内部和外部)两次声明for
,并使用两种不同的类型([]string
和{{ 1}})。外部作用域变量未使用,因此也应引起编译错误。[]int
-再次,这应该导致编译器错误,而不是错误的行为。鉴于代码中存在编译错误,或者您的帖子中缺少一些关键代码,或者您没有注意到/提及编译错误。
main中的正确代码为:
playerData2