Go 如何检查int变量是否已设置?

Go 如何检查int变量是否已设置?,go,Go,假设我有一个变量num 在计算if语句之前,我需要首先检查是否已设置了此变量。通常我会使用-1、0或math.MaxInt32/math.MinInt32,但对于此任务,我需要检查我的程序是否已设置其值 我尝试了nums:=nil,在我的if语句中,我得到了类似if nums==nil | |…… 但是当创建nums变量时,我惊讶地发现错误无法将nil转换为int类型。我怎样才能实现我想做的事 为了明确起见:这是一个leetcode,不能控制输入,他们在里面放了各种数字,包括math.MaxIn

假设我有一个变量
num

在计算
if
语句之前,我需要首先检查是否已设置了此变量。通常我会使用
-1
0
math.MaxInt32/math.MinInt32
,但对于此任务,我需要检查我的程序是否已设置其值

我尝试了
nums:=nil
,在我的
if
语句中,我得到了类似
if nums==nil | |……

但是当创建
nums
变量时,我惊讶地发现错误
无法将nil转换为int类型。我怎样才能实现我想做的事

为了明确起见:这是一个leetcode,不能控制输入,他们在里面放了各种数字,包括math.MaxInt32、math.MinInt32

完整代码:

func thirdMax(nums []int) int {

    dict := make(map[int]int, 0)

    varmaxOne := math.MinInt32
    maxTwo := math.MinInt32
    maxThree := math.MinInt32


    for _, value := range nums {

        if value >= maxOne && dict[value] < 1 {

            maxThree = maxTwo
            maxTwo = maxOne
            maxOne = value

        }else if value >= maxTwo && dict[value] < 1{
            maxThree = maxTwo
            maxTwo = value
        } else if value >= maxThree && dict[value] < 1 {
            maxThree = value
        }

        dict[value] += 1
    }

    if maxThree == math.MinInt32 {
        return maxTwo
    }
    return maxThree

}

func max(a int, b int) int {
    if a > b {
        return a
    }
    return b
}

上面的代码使用了
math.MinInt32
,但输入失败。想法是使用
nil
,并在
if
语句中进行检查,但如上所述失败。

正如注释所示,Go中所有int类型的零值都是
0
。如果
0
是一个可能的数字值,并且您需要检查它是否已被赋值,那么您可能希望使用附加了一些元数据的结构类型,而不是原语类型

像往常一样,对于这类问题,在标准库中也有先例


这些类型也可以通过实现
Scanner
来证明,但在需要检查原语值是否真的应该等于Null而不是零值时,您可以使用相同的想法。

如注释中所述,您无法检查是否设置了
int

如果您在输入中得到该值,则使用
math.MinInt32
作为信号值将失败

因此,如果您想以这种方式实现它,唯一的选择就是使用指针(
*int

使用指针,您可以检查它们是否已设置,因为它们以
nil
值开始,正如您所期望的那样

但是,由于需要使用指针和引用,因此实现的逻辑会变得更加复杂

请参阅下面一个可能的实现,尝试使用与您发布的相同的逻辑,只是更改为使用指针

另一种选择可能是对数组进行排序,然后使用已排序的元素查找第三个元素

游乐场连接:

func thirdMax(nums[]int)int{
dict:=make(映射[int]int,0)
//这些将以“零值”开始
var maxOne*int
var maxTwo*int
变量maxThree*int
对于u,值:=范围nums{
如果maxOne==nil | | value>=*maxOne&&dict[value]<1{
maxThree=maxTwo
max2=maxOne
maxOne=new(int)
*maxOne=值
}如果maxtow2==nil | | value>=*maxtow2&&dict[value]<1,则为else{
maxThree=maxTwo
maxTwo=新(int)
*maxTwo=值
}否则,如果maxThree==nil | | value>=*maxThree&&dict[value]<1{
maxThree=新(int)
*maxThree=值
}
dict[value]+=1
}
如果maxOne==nil{
死机(“不适用于空输入数组!”)
}
如果maxTwo==nil{
return*maxOne
}
如果maxThree==nil{
return*max2
}
return*maxThree
}

set是什么意思?非初始化变量将保留其类型的零值。整数只能保留整数值。如果要检查其他可能的状态,则需要另一种类型,可能是
*int
?有趣的。那么每种类型都有自己的“零”?让我试试,是的,每种类型都有一个。是的,每种类型都有一个“零值”。对于
int
来说,毫不奇怪,“零值”是
0
“那么您可能希望使用附加了一些元数据的结构类型,而不是原语类型。”---真的吗??所有这些都只是为了检查程序是否分配了变量???@maxflow,如果您对这种情况进行一些思考,您会得出一个(明显的)结论,为了跟踪是否分配了变量,编译器和/或运行时必须以某种方式保持对该事实的跟踪。这基本上意味着在某个地方存储一个标志值,然后在每次设置其成对变量时设置它(因此我们有两个内存存储,而不是一个),或者检查它是否已经初始化(因此除了存储之外,我们还有一个内存读取)……或者以更昂贵的方式进行,比如用一个“透明”)指针指向堆分配的整数值,并在每次访问时“追逐”该指针值,以便在第一次访问时(当该指针为
nil
)实际上,分配值和写指针。现在请停止并给出更多的思考。基本上,你会要求编译器/运行时支付所有变量的成本,即使99.9%的变量是不需要的……现在考虑一下,以便访问这种“保护”。“变量透明对于Go的内存模型(例如,整数变量不能被半初始化),编译器/运行时需要在每次访问此类变量时使用内存访问同步。这是一个疯狂的代价。嗯,在脚本语言中可能没有那么疯狂,在脚本语言中,程序的速度预先定义为糟糕,但在围棋中则没有,围棋是合理的“接近金属”,让您能够充分控制内存布局和数据访问。
func TestThirdMax(t *testing.T) {
    //array := []int{2, 3, -1, -9, 11, 4, 3, 0, -100}
    //array := []int{2, 2, 3, 1}
    array := []int{1,2,-2147483648}
    //array := []int{3,2,1}
    result := thirdMax(array)

    if result != 2 {
        t.Errorf("Expected 2, but it was %d instead.", array)
    }
}
func thirdMax(nums []int) int {

    dict := make(map[int]int, 0)

    // these will start with "nil values"
    var maxOne *int
    var maxTwo *int
    var maxThree *int


    for _, value := range nums {

        if maxOne == nil || value >= *maxOne && dict[value] < 1 {

            maxThree = maxTwo
            maxTwo = maxOne
            maxOne = new(int)
            *maxOne = value

        }else if maxTwo == nil || value >= *maxTwo && dict[value] < 1{
            maxThree = maxTwo
            maxTwo = new(int)
            *maxTwo = value
        } else if maxThree == nil || value >= *maxThree && dict[value] < 1 {
            maxThree = new(int)
            *maxThree = value
        }

        dict[value] += 1
    }

    if maxOne == nil {
        panic("does not work with empty input array!")
    }
    if maxTwo == nil {
        return *maxOne
    }
    if maxThree == nil {
        return *maxTwo
    }
    return *maxThree

}