我在 Python 里用 is 判断两个数字相不相等,小数字时一直好好的,换成大数字后判断突然全错了,我对着这个时对时错的比较排查了大半天的复盘

我随手用 is 判断两个值相等,测试时用小数字 a=100,b=100,a is b 是 True 一切正常就上线了。结果线上换成大数字 a=1000,b=1000,a is b 居然返回 False;比较内容相同的字符串也时 True 时 False,逻辑时对时错。深挖才懂我混淆了 is 和 ==:== 比的是"值是否相等"(__eq__),is 比的是"是不是同一个对象"(id/内存地址),两码事!小数字之所以碰巧对,是因为 Python 缓存了 -5~256 的小整数(小整数池)、短字符串也常被驻留复用,a=100,b=100 恰好指向同一缓存对象 is 才 True,纯属缓存巧合;一旦超出 256 或动态生成字符串,就是两个独立对象、地址不同,is 如实返回 False。小对象缓存"好心"地用巧合掩盖了我的错误,让它在小数据下碰巧能跑。这篇从 is 与 == 的本质区别讲起,到比较值一律用 ==、is 只留给 None/单例的正解、小对象缓存等碰巧成立的实现细节、is/== 场景速查、其他"小数据碰巧能跑"的坑、用 id() 看清真相,以及那句最戳心的——它能跑和它是对的是两回事,要追求理解原理上的正确而非碰巧能跑的正确。

我在 Python 里用 is 判断两个数字相不相等,小数字时一直好好的,换成大数字后判断突然全错了,我对着这个时对时错的比较排查了大半天的复盘

这是一个让我对 Python 的 is== 彻底分清的故事。我有段代码,要判断两个值是不是相等,我随手用了 is:if a is b:。我测试的时候,用的都是小数字(比如 a = 100, b = 100),a is b 返回 True,一切正常,我就放心地上线了。可线上跑起来,诡异的事发生了:当实际数据是大一点的数字(比如 a = 1000, b = 1000)时,a is b 居然返回 False!明明两个值一模一样,判断却失败了;同样地,用 is 比较两个内容相同的字符串,有时返回 True、有时返回 False,飘忽不定,导致我的逻辑时对时错

我当时百思不得其解:同样是判断相等,为什么小数字行、大数字就不行?is 到底在比什么?我顺着这个现象深挖,才终于揭开真相,补上了我对 Python 一个最基础、却极易踩的认知漏洞:问题的核心,是我混淆了 is== 这两个本质完全不同的运算符。我一直想当然地以为,"is== 都是判断相等,差不多";可真相是:== 比较的是"是否相等"(调用 __eq__),而 is 比较的是"是不是同一个对象"(即两者的内存地址(id())是否相同);它们是两码事!那为什么小数字用 is 又"碰巧"对了呢?这才是最坑的地方:Python 为了优化性能,缓存(复用)了一批"常用的小对象"——具体说,是-5 到 256 之间的小整数,做成了"单例",全程序共用同一个对象(这叫"小整数池");此外,一些短字符串也会被"驻留(intern)"、复用同一个对象。所以,当 a = 100, b = 100 时,它俩恰好指向了缓存里的同一个对象,is 自然返回 True——但这纯属"缓存的巧合",并不是因为 is 能比较值!而一旦数字超出了 256(如 1000),Python 不再缓存,a = 1000b = 1000 就是两个独立创建的、不同的对象,内存地址不同,is如实地返回了 False我这才痛彻地明白:我用 is 比较值,从一开始就是错的;只是 Python 的小对象缓存,"好心"地用一个巧合,替我掩盖了这个错误,让它在小数据下"碰巧能跑",从而给了我一种虚假的正确感,直到数据变大,真相才暴露is== 的区别,是 Python 的基础常识,但"小对象缓存"这个性能优化,却让这个区别,变成了一个极其隐蔽、极易让人在小数据下被蒙混过关的陷阱;比较值,永远、永远要用 ==;is 只用来判断"是不是同一个对象",最典型的场景,是判断 x is None

故障现场:用 is 比较值,被小对象缓存"蒙混过关"

我把这个"时对时错"的现场,摊开给你看:

# ✗ 灾难: 用 is 比较"值是否相等", 被小对象缓存蒙混过关
# 小整数(-5~256): 被缓存复用 → is 碰巧为 True(假象!)
a = 100
b = 100
print(a is b)    # ✗ True —— 但这是缓存的巧合, 不是因为 is 能比值!
print(a == b)    # ✓ True —— 这才是真正在比值

# 大整数(>256): 不缓存, 是两个独立对象 → is 为 False(真相暴露!)
x = 1000
y = 1000
print(x is y)    # ✗ False! 明明值相等, is 却 False
print(x == y)    # ✓ True

# 字符串: 短的/字面量常被"驻留"复用, 动态生成的则不一定
s1 = "hello"
s2 = "hello"
print(s1 is s2)              # 可能 True(驻留)
s3 = "".join(["h","e","l","l","o"])   # 动态生成
print(s1 is s3)             # ✗ 可能 False! 值相同但不是同一对象
print(s1 == s3)             # ✓ True

# is 和 == 到底比什么?
#   ==  : 比较"值是否相等"(调用 __eq__)。 ← 比较值就用它!
#   is  : 比较"是不是同一个对象"(id() 是否相同, 即内存地址)。

# 为什么小数字 is 也对?(最坑的"巧合")
#   - Python 缓存了 -5~256 的小整数(小整数池), 全程序共用同一对象。
#   - 短字符串也常被驻留(intern)复用。
#   - 所以 a=100,b=100 恰好指向同一缓存对象 → is 为 True(纯属巧合)。
#   - 超出范围 / 动态生成 → 独立对象 → is 为 False。

# 根因: 用 is 比较值(本应用 ==), 小对象缓存让 is 在小数据下"碰巧对",
#   掩盖了错误; 数据变大/动态生成时, is 如实返回 False, 逻辑就崩。

看着这段"小数字对、大数字错"的代码,我才算彻底想明白了根源。问题的核心,是我is 去比较"值是否相等",而这本该用 ==is== 到底比什么?== 比较"值是否相等"(调用 __eq__)——比较值就用它;is 比较"是不是同一个对象"(id()/内存地址是否相同)那为什么小数字用 is 也对(最坑的巧合)?因为 Python 缓存了 -5~256 的小整数(小整数池)、全程序共用同一对象,短字符串也常被驻留(intern)复用;所以 a=100, b=100 恰好指向同一缓存对象、is 为 True(纯属巧合);而超出范围(如 1000)或动态生成的字符串,是独立对象,is 就返回 False归根结底:is 比较值(本应用 ==),小对象缓存让 is 在小数据下"碰巧对"、掩盖了错误;数据变大或动态生成时,is 如实返回 False,逻辑就崩——这,就是根源。

第一件事:搞懂 is 与 == 的本质区别

定位到根源,我必须把 is== 的区别,从根上彻底搞清楚:

is 比"对象身份"(内存地址), == 比"值"; 比较值永远用 ==

# 两者的本质:
#   == : 调用 __eq__, 比较"值/内容是否相等"。两个不同对象, 值相同 → ==为True。
#   is : 比较 id() 是否相同, 即"是不是内存里同一个对象"。

# 类比:
#   == : "这两本书内容一样吗?"(可以是两本不同的书, 内容相同)
#   is : "这是同一本书吗?"(同一个物理实体)

# 为什么会混: 小对象缓存让 is "碰巧"等于 ==
#   - 小整数池: -5 ~ 256 的整数被缓存成单例 → is 这些数碰巧为 True。
#   - 字符串驻留: 字面量/标识符样的短字符串被复用 → is 碰巧为 True。
#   - 这是"实现细节/性能优化", 不是语言保证! 不能依赖!
#   → 同样的代码, 数字大小/字符串来源一变, is 的结果就变。

# 什么时候该用 is?(只有这几种)
#   - 判断单例: x is None / x is True / x is False。
#   - 判断"是不是同一个对象"(故意要比身份, 如缓存命中、循环引用检测)。
#   - 枚举/哨兵对象的比较。

# 什么时候该用 ==?
#   - 比较值! 数字、字符串、列表内容、任何"内容是否相等"的判断。
#   - 99% 的"相等判断", 都该用 ==。

# 特例: None / True / False 是单例, 用 is 判断最规范、最快。
#   if x is None:    ✓ 推荐(PEP8 也这么建议)
#   if x == None:    △ 能用但不规范(且自定义 __eq__ 可能出意外)

# 关键认知: 比较值用 ==, 判断"同一对象/单例"用 is; 别被小对象缓存骗了。

# 核心: is 比对象身份(地址)、== 比值; 比较值永远用 ==, is 只用于 None/单例;
#   小整数池和字符串驻留会让 is 在小数据下"碰巧对", 是陷阱别依赖。

原理终于清晰了。两者的本质:== 调用 __eq__、比较"值/内容是否相等"(两个不同对象、值相同,== 为 True);is 比较 id() 是否相同、即"是不是内存里同一个对象"打个比方:== 是问"这两本书内容一样吗"(可以是两本不同的书),is 是问"这是同一本书吗"(同一个物理实体)。为什么容易混?因为小对象缓存让 is "碰巧"等于 ==:小整数池(-5~256 被缓存成单例)、字符串驻留(短字符串被复用),让 is 这些值碰巧为 True;但这是"实现细节/性能优化",不是语言保证,绝不能依赖——数字大小/字符串来源一变,is 的结果就变什么时候该用 is?只有几种:判断单例(x is None/x is True/x is False)、故意要比"是不是同一个对象"、枚举/哨兵对象比较什么时候该用 ==?比较值!数字、字符串、列表内容……99% 的"相等判断"都该用 ==特别地:None/True/False 是单例,用 is 判断最规范、最快(if x is None 是 PEP8 推荐写法)。由此,我刻下一个关键认知:比较值用 ==,判断"同一对象/单例"用 is;别被小对象缓存骗了。归根结底:is 比对象身份(地址)、== 比值;比较值永远用 ==,is 只用于 None/单例;小整数池和字符串驻留会让 is 在小数据下"碰巧对",是陷阱别依赖。

第二件事:正解——比较值用 ==,is 只留给 None/单例

搞懂了原理,正解就极其简单了:比较值,一律用 ==;is 只用来判断 None 等单例

# ✓ 正解一: 比较值, 一律用 ==
a = 1000
b = 1000
if a == b:                       # ✓ 比值, 永远正确, 不受缓存影响
    print("相等")

s1 = "hello"
s3 = "".join(["h","e","l","l","o"])
if s1 == s3:                     # ✓ 比值, 动态生成的字符串也正确
    print("字符串相等")

# ✓ 正解二: is 只用于判断 None / True / False 单例
def f(x=None):
    if x is None:                # ✓ 推荐: 判 None 用 is(规范、快、不被 __eq__ 干扰)
        x = []
    # ✗ 别写 if x == None: 不规范, 且若 x 自定义了 __eq__ 可能出意外
    return x

# ✓ 正解三: 判断布尔单例(谨慎, 通常直接用真值判断更好)
if flag is True:    # 极少这么写, 一般直接 if flag:
    ...

# ✓ 正解四: 故意要比"是不是同一个对象"时, 才用 is
cache = {}
obj = cache.get(key)
if obj is sentinel:              # ✓ 用哨兵对象判断"是否命中", 比身份是合理的
    ...

# 一句话决策:
#   - 问"值一样吗?" → ==
#   - 问"是同一个东西吗?" / "是不是 None?" → is

# ⚠ 自定义类: 默认 == 等同于 is(比地址), 想按值比较要重写 __eq__(见 Java equals 篇同理)。

# 核心: 比较值一律用 ==(不受小对象缓存影响, 永远正确);
#   is 只留给 None/单例判断, 或故意比较对象身份的场景。

修复其实一字之差,却根除了问题。正解一,比较值一律用 ==:无论是大整数 1000 还是动态生成的字符串,== 比的是值,永远正确、完全不受缓存影响正解二,is 只用于判断 None 等单例:if x is None:推荐写法(规范、快、且不会被自定义的 __eq__ 干扰)——别写 if x == None(不规范,且若对象自定义了 __eq__ 可能出意外)。正解三/四:判断布尔单例(虽然一般直接 if flag: 更好)、或故意要比"是不是同一个对象"(如用哨兵对象判断缓存是否命中)时,才用 is一句话决策:问"值一样吗?"→ ==;问"是同一个东西吗?/是不是 None?"→ is还有个关联点:自定义类的 默认 == 其实等同于 is(比地址),想按值比较要重写 __eq__(和 Java 重写 equals 同理)。归根结底:比较值一律用 ==(不受小对象缓存影响、永远正确);is 只留给 None/单例判断,或故意比较对象身份的场景。

第三件事:小对象缓存背后,Python 的几个"性能优化巧合"

这次踩坑让我意识到,Python 里还有不少"性能优化带来的、看似神奇却不能依赖"的行为。我把它们梳理了一遍:

# Python 里几个"碰巧成立、却不能依赖"的实现细节:

# 1. 小整数池: -5 ~ 256 被缓存
print(256 is 256)    # True (缓存)     ← 别依赖
print(257 is 257)    # 可能 False (看上下文/解释器)
#   → 这是 CPython 的优化, 不是语言规范; 比较数值永远用 ==。

# 2. 字符串驻留(interning): 标识符样的短字符串被复用
a = "hello"; b = "hello"
print(a is b)        # 常 True (驻留)  ← 别依赖
c = "hello world!"   # 含空格/特殊字符的, 不一定驻留
print(c is "hello world!")  # 可能 False
#   → 比较字符串永远用 ==。

# 3. 不可变对象可能被复用(元组等), 但同样不保证。

# 这些"缓存/复用"的目的:
#   - 节省内存、加速创建(小整数、常用字符串用得极频繁)。
#   - 是 CPython 的实现优化, 其他解释器(PyPy等)行为可能不同。

# 你能依赖的 vs 不能依赖的:
#   ✓ 能依赖: == 比值的结果、is None 判断 None。
#   ✗ 不能依赖: is 比较两个"值相等的非单例对象"的结果(看缓存, 不确定)。

# 一个验证小工具: 用 id() 看是不是同一对象
print(id(a), id(b))   # 相同 = 同一对象(is 为 True); 不同 = is 为 False

# 核心: 小整数池/字符串驻留是 CPython 的性能优化(碰巧让 is 成立), 不是语言保证;
#   绝不能依赖它们; 比较值永远 ==, 判 None 用 is。

原来 Python 里这类"碰巧成立的实现细节"还不少。小整数池:-5~256 被缓存,256 is 256 是 True、但 257 is 257 可能 False;字符串驻留:标识符样的短字符串被复用、is 常为 True,但含空格/特殊字符的不一定驻留;不可变对象(元组等)也可能被复用,但同样不保证这些"缓存/复用"的目的,是节省内存、加速创建(小整数、常用字符串用得极频繁),但这是 CPython 的实现优化,其他解释器(PyPy 等)行为可能不同所以要分清能依赖的 vs 不能依赖的:✓ 能依赖:== 比值的结果、is None 判断 None;✗ 不能依赖:is 比较两个"值相等的非单例对象"的结果(看缓存、不确定)。(想验证两个变量是不是同一对象,可以用 id() 看地址。)它给我的启发是:编程语言里,有"语言规范保证的行为"和"某个实现碰巧表现出的行为"——前者你可以放心依赖,后者绝不能;而区分这两者,正是写出"可移植、可靠"代码的关键is 在小整数上"碰巧对",就是典型的"实现细节",依赖它,就是在把代码的正确性,建立在一个随时可能变化的沙地上

下面这张图,是这次"is 比较值"事故的成因与解法:

第四件事:is 与 == 的使用场景速查

这次踩坑后,我把 is== 的使用场景,整理成一张速查表,以后一看就知道该用哪个。

场景 该用 说明
判断两个数字/字符串值相等 == 比值, 不受缓存影响
判断列表/字典内容相等 == 逐元素比值
判断 x 是不是 None is None 规范、快、不受 __eq__ 干扰
判断 x 是不是 True/False 一般直接 if x / 必要时 is 少用 == True
判断是不是同一个对象 is 故意比身份(缓存命中/哨兵)
自定义对象按值比较 == (需重写 __eq__) 默认 == 等同 is, 要重写才比值

这张表,把"该用 is 还是 =="彻底说清了。规律极其简单:绝大多数"相等判断"(数字、字符串、列表、字典的值相等)都用 ==;is 几乎只在一个高频场景出现——判断 x is None(这是规范、最快、且不受自定义 __eq__ 干扰的写法),其余就是故意要比"对象身份"的少数场景(缓存命中、哨兵对象)。有两个小提醒:判断布尔,一般直接 if x: 就好,少用 == True(更别用 is True 除非真要严格区分);自定义对象想按值比较,记得重写 __eq__(因为默认的 == 等同于 is、比的是地址)。它给我的启发是:很多语言的基础运算符,看起来简单,却各有精确的语义边界;is== 就是一对最典型的例子——记住"值用 ==、身份/None 用 is"这条简单的规则,就能避开绝大多数相关的坑。基础不牢,地动山摇;而把这些"看似简单"的基础,真正搞精确,正是写出可靠代码的地基。

第五件事:Python 里其他"小数据下碰巧能跑"的隐蔽坑

这次"小数字碰巧对"的经历,让我警觉:Python 里还有不少"在小数据/特定条件下碰巧能跑、换个场景就崩"的坑。我把它们一并梳理了。

碰巧能跑的场景 翻车的场景
用 is 比较值 小整数/短字符串(缓存) 大整数/动态字符串(本文)
可变默认参数 只调一次时 多次调用共享同一默认对象
依赖 dict 有序 Py3.7+ 碰巧有序 老版本/依赖排序逻辑时
浮点 == 比较 简单整数值的浮点 0.1+0.2 != 0.3 等精度问题
遍历时修改集合 元素少/没触发扩容 元素多时 RuntimeError
捕获循环变量的闭包 循环内立即用 留到循环后用(全取末值)

这张表,让我看清了这类坑共同的、最阴险的特征:它们不是"一上来就报错",而是"在某些条件下碰巧能正常工作"——而这份"碰巧能跑",恰恰是最危险的:它给了你虚假的信心、骗过了你的测试(如果测试数据恰好落在"碰巧对"的范围内),然后埋伏在代码里,等数据或条件一变,才在线上、在你最意想不到的时候,暴露出来无论是is 比较值(小整数碰巧对)、可变默认参数(只调一次碰巧对)、依赖 dict 有序(新版本碰巧对)、浮点 ==(简单值碰巧对)、遍历时改集合(元素少碰巧对)、还是闭包捕获循环变量(立即用碰巧对)——它们都在用"局部的、偶然的正确",掩盖着"全局的、本质的错误"。它给我的最大启发是:测试通过、demo 能跑,绝不等于代码是对的;尤其要警惕那些"在我测试的这组数据下能跑"的代码——它可能只是碰巧对了。真正可靠的代码,要建立在"理解其行为在所有情况下都正确的原理"之上,而不是"它在我试的几个例子上没出错"这种脆弱的经验之上知其然,更要知其所以然——这,是避开这一整类"碰巧能跑"陷阱的唯一办法

第六件事:写一个相等判断时,我现在会怎么决策

现在,每当我要写一个"相等判断",脑子里都会过一遍这张(其实很简单的)决策图——核心就一问:我是在问"值一样吗"还是"是不是同一个东西"?

这张图虽小,却能挡住一整类坑。核心就一个判断:我想判断什么?——值/内容是否相等 → ==;是不是 Noneis None;是不是同一个对象/单例 → is==,还要多看一眼:是自定义对象吗?是的话,确保重写了 __eq__(否则 == 会退化成比地址);内置类型直接 == 即可。None:用规范的 if x is None,别写 == None这套判断,简单到几乎是条件反射,但它能让我永远不再被"小对象缓存"的巧合骗到——核心始终是那句:分清"值相等"和"同一个对象",绝大多数时候,你要的都是前者(==)。

我立下的几条规矩

这场"is 比较值时对时错"的事故,换来了我写 Python 时,刻进骨子里的几条铁律:

  1. 比较值,永远用 ==。数字、字符串、列表、字典的内容相等判断,一律 ==,不受小对象缓存影响。
  2. is 只用于 None/单例/比对象身份。最高频的是 if x is None;其余就是故意比"是不是同一个对象"。
  3. 判 None 用 is None,别用 == None。规范、快、且不会被自定义 __eq__ 干扰。
  4. 别依赖小整数池/字符串驻留。is 在小整数/短字符串上"碰巧对"是 CPython 实现细节,不是语言保证,绝不能依赖。
  5. 自定义对象要按值比较就重写 __eq__。默认 == 等同 is、比地址(配合 hashCode 篇的 Java 同理)。
  6. 警惕"碰巧能跑"的代码。测试数据恰好落在"碰巧对"的范围,会给你虚假信心;要理解原理,别靠几个例子没出错。
  7. 知其然更知其所以然。可靠不是"它在我试的例子上对了",而是"我理解它在所有情况下都对"。

附:几行代码亲眼看清 is 的"碰巧"

口说无凭。下面这几行,用 id() 亲眼看清 is 为什么"小数字对、大数字错",跑一遍胜过千言:

# 实验1: 小整数被缓存 → is 碰巧 True
a = 100
b = 100
print(a is b, id(a) == id(b))   # True True  —— 同一个缓存对象

# 实验2: 大整数不缓存 → is False(值相等但不同对象)
x = 1000
y = 1000
print(x is y, id(x) == id(y))   # False False —— 两个独立对象!
print(x == y)                    # True        —— 值是相等的

# 实验3: 找出小整数池的边界(-5 ~ 256)
print(256 is 256)                # True  (在池内)
n1 = 257; n2 = 257
print(n1 is n2)                  # 常 False (出池了, 取决于上下文)

# 实验4: 字符串驻留 vs 动态生成
s1 = "hello"
s2 = "hello"
print(s1 is s2)                  # 常 True (驻留)
s3 = "hel" + "lo"                # 编译期可优化, 可能 True
s4 = "".join(["h","e","l","l","o"])  # 运行期动态生成
print(s1 is s4, s1 == s4)        # False True  —— is 错, == 对!

# 实验5: None 是单例, is 永远可靠
print(None is None)              # True (永远)
x = None
print(x is None)                 # True ✓ 这才是 is 的正确用法

# 核心: id() 揭示真相 —— is 比的是 id(地址), 小整数/短字符串碰巧同 id 才 is True;
#   大整数/动态字符串 id 不同 is 就 False; 比较值永远 ==, 判 None 才用 is。

这几行代码,把 is 的"碰巧",id() 照得清清楚楚实验 1 和 2 是最直接的对比:a=100, b=100id(a) == id(b)(同一个缓存对象,所以 is True);而 x=1000, y=1000id(x) != id(y)(两个独立对象,所以 is False),但 x == y 是 True(值确实相等)——id() 一打印,真相大白:is 比的根本是地址,跟值没关系实验 3 还能亲手探出小整数池的边界(256 在池内、257 出池);实验 4 展示了字符串驻留 vs 动态生成的差别(s1 is s4 是 False、但 s1 == s4 是 True);实验 5 则印证了 None is None 永远可靠——这才是 is 的正确用武之地。这,正是我想用这几行代码,留给每一个学 Python 的人的最后一课:当你对一个行为感到困惑时(尤其是 is 这种"有时对有时错"的),别去猜、别去背结论,而是用 id()type() 这些"探针",把对象的真实身份打印出来,让 Python 亲口告诉你它内部到底是怎么回事。一次"用 id() 看个明白"的实验,胜过十遍"记住 is 和 == 的区别"的死记硬背;而那些通过亲手探查得来的理解,会真正变成你的、再也忘不掉的认知

写在最后

回头看,这场由 is== 混用引发的事故,真正教给我的,是一个比"分清这俩运算符"本身更深的道理:编程中最危险的错误,往往不是那些"一上来就崩"的错误(它们反而容易被发现和修复),而是那些"在大多数情况下碰巧表现正确、只在特定边界条件下才暴露"的错误——因为它们能骗过你的测试、骗过你的直觉,潜伏到生产环境,在最坏的时机给你致命一击我的 is 错误,正是被 Python 那份"好心"的小对象缓存,用一个美丽的巧合,完美地伪装了起来;它在我所有的小数据测试里,都"表现得无可挑剔",让我对一个根本性的错误,毫无察觉。这让我深刻地意识到:"它能跑"和"它是对的",是两件截然不同的事;而一个工程师的成熟度,很大程度上体现在他是否能看穿"碰巧能跑"的假象,去追问那个"为什么对、又会在什么条件下不对"的本质原理所以,写代码时,要时刻对那份"它跑通了"的轻松保持一丝警惕,多问自己一句:"它是真的对,还是碰巧对?它的正确性,建立在我理解的原理上,还是建立在我试过的几个例子上?"。追求"理解原理上的正确",而非"碰巧能跑的正确"——这,是我用一次"is 比较值"的事故,换来的、关于 Python、也关于编程严谨性的、最朴素也最深刻的领悟。如果这篇复盘,能让你以后写相等判断时,条件反射地用对 ==is,并对"碰巧能跑"多一分警惕,那我对着那个时对时错的判断熬的这大半天,就值了。

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

我的 AI Agent 调工具查数据时返回了个空结果,它却当成查到了、基于这个空结果一路推理下去,最后给出一个看起来很完整其实全错的答案,我排查了大半天的复盘

2026-6-2 3:30:30

技术教程

我在 JavaScript 里用双等号判断相等,结果空字符串等于 0、字符串 0 等于数字 0,各种本不该相等的东西判出来都相等,我排查了大半天的复盘

2026-6-2 3:43:20

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索