
字节笔记本
2026年10月7日 · 约 6 分钟读完
这组数的最大值是八
切片是 4、8、5。变量从 -1 开始。循环里谁更大就记下谁。打印用的是 fmt.Print。这组数走完,印出的是 8。初值不在切片里。切片里的数若都不大于 -1,印出来的仍是 -1。

三次比较
x 是 []int{4, 8, 5}。y 先等于 -1。for 用 range,下标用下划线丢掉,只拿元素 elt。elt 大于 y 时,把 y 改成 elt。
第一次元素是 4。4 大于 -1,y 变成 4。第二次是 8。8 大于 4,y 变成 8。第三次是 5。5 不大于 8,y 保持 8。循环结束,fmt.Print(y) 印出 8,后面不加换行。对话给出的结果就是 8。这三步和结果一致。
下标被丢掉,是因为比较不需要位置。若要同时知道最大值在第几位,不能用下划线,要留下序号。这一段没有这个需求。
片段里没有写出 fmt 的导入。完整程序要带上格式化包,否则打印这一行过不了编译。输出是 8 这件事,建立在导入已经补上的前提下。
初值比切片里任何数都大时会失败
-1 能当这组正数的起点,是因为 4、8、5 都比 -1 大,第一次比较就会把起点换掉。若切片是 -2 和 -5,两次都不大于 -1,y 保持 -1。-1 并不是切片里的元素。空切片一次循环都不会进,印出的也是 -1。所以这段代码的正确范围,是切片里至少有一个大于 -1 的数。对话里的例子刚好满足,不能把初值 -1 当成通用的最大值起点。
更稳的起点是切片的第一个元素,从第二个开始比。空切片要先拒绝,再谈最大。不要用一个哨兵去代表“还没看到元素”,除非哨兵一定小于任何可能的元素。整数没有这样的业务哨兵时,就用元素自己。
fmt.Print 和 fmt.Println 差在换行。后面若还有输出,会粘在 8 后面。要单独一行,用带换行的那个。数值不会因此变成别的数。

先让例子成立,再换起点
这组 4、8、5 的最大值是 8,三次比较可以留在注释里。把同一段函数拿到可能含负数或空切片的地方之前,先改起点。改完用原来的三个数再跑一次,确认印出的仍是 8。再补一组全负数和一组空切片,确认不会印出哨兵。
从负一出发,第一眼看到 4,因为 4 更大,记下 4。再看到 8,8 比 4 大,记下 8。最后看到 5,5 不比 8 大,保持 8。打印不加换行。这和对话给出的结果一致。下标没有参与比较。若要报出最大值的位置,循环必须留下序号。8 在这组里的位置是第二位,下标从零数是 1。这段代码没有保留这个位置。
哨兵负一只在所有候选都可能大于它时才安全。全是更小的负数时,循环一次都不会更新,打印的是哨兵而不是切片中的最大元素。空切片同样打印哨兵。调用方会把负一当成业务数据。改法是空切片直接返回,非空则用第一个元素当起点,从下一个开始比。改完再用 4、8、5 验证,结果仍应是 8。再验证一组负数,结果应是那组里较大的一个,而不是负一。
片段能印出 8,还要求格式化包已经导入。没有导入时,失败发生在编译,不会印出错误的最大值。不要把编译错误说成算法算错。算法在这组正数上是对的,在空切片和全负数上是错的。两件事分开测。
切片里的顺序是四、八、五。记下最大值的变量从负一开始。四比负一大,于是变成四。 八比四更大,于是变成八。五不比八大,于是保持八。打印出来的就是八,而且这一次打印不换行。 八是在第二次比较时定下来的。最后一个元素五并没有获胜。不要把打印结果理解成来自最后一次元素。 下标从零数,四在第零位,八在第一位,五在第二位。循环把位置丢掉了,只留下数值。 只需要印出数字时,丢掉位置没有关系。要在界面上标出是哪一格,就必须把序号留下来,八的序号是一。 负一并不在切片里面。它能充当起点,只是因为这组数都比它大,第一次比较就会把它换掉。 空切片一次都不会进入循环,印出来的仍是负一。调用方无法知道这是哨兵,还是切片里真有这个数。 全是更小的负数时,一次都不会更新,印出来的也是负一。那不是切片中的最大元素。 所以不要把这段原样用到可能为空、可能为负的数据上。空切片要在循环开始前返回。 非空切片用第一个元素当起点,从下一个元素开始比。这样结果一定来自切片自己。 改完起点之后,再用四、八、五跑一遍。结果必须仍是八。防止改起点时把原来正确的结果改丢。 再准备一组全是负数的例子。结果应是那组里较大的数,并且这个数能在切片里找到。 片段里没有写出格式化包的导入。没有导入时失败发生在编译,不会印出一个错误的最大值。 先补上导入,再看数值。不要在编译失败的时候去改比较条件。 需要单独一行时,换会换行的打印。不要在数字后面加空格,假装已经分行。空格和换行不是一回事。 这组正数的三步可以留在说明里,作为八是怎么来的记录。哨兵负一不能跟着被拿到别的数据上。 替换序列可以写成负一到四,再到八,然后保持。最后印出的八就是这次保持的结果。 若切片里只有五,五会替换负一。现在的五没有替换,是因为当时已经记下了八。 空切片的测试不要期望八,也不要期望负一。它应该在比较开始之前就结束。 全负数的最大元素一定在切片里。用首元素当起点,才能保证不会交出去一个外面的哨兵。 编译器指出缺少格式化包时,先补导入。导入补上之后,再用这组数看是否印出八。 打印不换行时,若测试按行读取,后面的输出会粘在八后面。要行边界就换会换行的函数。 位置和数值分开。这段代码只要数值。高亮第几格时才把丢掉的下标加回来。 改起点之后的三组都要跑。正数仍是八,空切片不再是负一,负数取切片中较大的那个。 负一能在这组正数上工作,不能当成整数切片的通用起点。没有比所有整数都小的业务哨兵。 说明里留下三次比较,避免以后把八理解成别的公式算出来的。它就是第二次替换的结果。



