当前位置: 首页 > news >正文

【Janet】比较运算符

比较运算符用于比较值来建立相等和顺序。Janet 有两种比较运算符,分别叫做原始比较和多态比较。

原始比较运算符

原始比较运算符是 =<<=>>=。简单来说,每个运算符都可以用来比较两个值:如果 a < b, (< a b) 会返回真,否则返回假。同样 (= a b) 仅当 a==b 时返回真。

(= 3 3)          # true
(< 1 3)          # true
(>= :a :a)       # true
(> "bar" "foo")  # false -- strings compare lexicographically
(<= :bar :foo)   # true -- keywords compare lexicographically by keyword name
(= nil nil)      # true -- nil always equal to itself and only itself

更一般的,每个运算符都支持任意数量的参数(包括0),只要参数没有违反操作符定义的顺序就返回真。因此 (< 1 2 3) 返回真,但是 (> 3 2 4) 返回假。做为一个极端, (<) 返回真,因为它的(不存在的)参数没有违反它的顺序。

(= 1 1 1)  # true
(< 1 3 5)  # true
(>= 3 1 7) # false
(> 1)      # true

原始比较运算符为所有的 Janet 类型提供了一个总的排序,但是不同类型的值的比较结果可能会出乎你的意料。如果原始比较运算符的两个参数是不同类型的,它们会根据 Janet 内部的类型数字排序。这可能并不是用户所需要的,例如,比较 Janet int/s64 类型和 Janet 数字类型。

# surprisingly evaluates to false:
(= (int/s64 1) (int/u64 1))
# surprisingly evaluates to true but this due to Janet internal type number
# for int/u64 types being greater than the internal type number for numbers!
(< 3 (int/u64 2))

如果你不想根据类型数字比较不同类型(例如比较数值),可以使用下面的多态比较运算符。

多态比较运算符

多态比较运算符用来以其他方式比较不同类型而不是类型码。其语义由比较的类型决定。它的目的是以更正确的方式(相比于原始比较运算符)比较具有自然顺序的两个类型。

多态比较运算符包括 compare=compare<compare<=compare>compare>=。它们的用法与原始比较运算符相同:

(compare< 1 3)          # true
(compare> "bar" "foo")  # false -- strings compare lexicographically
(compare<= :bar :foo)   # true -- keywords compare lexicographically by keyword name
(compare= nil nil)      # true -- nil always equal to itself and only itself
(compare< 1 2 3)        # true -- just like <

当他用来比较 int/s64int/u64 和数字类型时,会得到正确的结果。

(compare= (int/s64 1) (int/u64 1))  # true -- they are "semantically" equal
(compare< 3 (int/u64 2))            # false -- semantically 3 is not < 2

通常多态运算符要比原始运算符慢,因此优先使用原始比较运算符,除非需要多态特性。

实现多态比较

如果只是将多态比较用于内置类型,可以跳过本章,本章将介绍如何为自定义类型实现多态比较。

多态比较使用 compare 函数来比较 Janet 值。对于 a<ba=ba>b compare 函数分别返回 -1,0 和 1。比较运算符,如 compare< 根据这个结果返回真或假(多参数情况会多次调用 compare)。 compare 函数的算法如下:

  • 如果 a 实现了 :compare(:compare a b) 不是空,则返回 (:compare a b)
  • 如果 b 实现了 :compare(:compare b a) 不是空,则返回 (- (:compare a b))
  • 其他情况返回 (cond (< a b) -1 (= a b) 0 1)

compare 方法最终会使用原始比较做为兜底,多态比较会产生 Janet 类型的全局顺序。

抽象类型的比较方法可以使用 C 实现,基于表的对象的 compare 函数可以使用 Janet 实现。

深度相等操作符

原始 = 操作符不会比较可变数据结构(数组,表和缓冲区)的内容。而是判断连个值是否是同一个对象。

# Even though they have the same contents these are considered *not* equal
(assert (not= @{:a 1} @{:a 1}))
(assert (not= @[:a :b] @[:a :b]))
(assert (not= @"abc" @"abc"))# primitive equal will return true if they are same object
(let [x @{:a 1}](assert (= x x)))# NOTE: = works as expected on immutable structures
(assert (= [:a :b] [:a :b]))
(assert (= {:a 1} {:a 1}))
(assert (= "abc" "abc"))

要比较可变数据结构的内容,使用 deep= 函数。这个函数像比较字符串一样比较缓冲区,并且递归地比较数组和表。

(assert (deep= [:a :b] [:a :b]))
(assert (deep= {:a 1} {:a 1}))
(assert (deep= "abc" "abc"))(assert (deep=@{ :x @[@{:a 1} 3 @"hi"] :y 2 }@{ :x @[@{:a 1} 3 @"hi"] :y 2 }))# NOTE deep= uses primitive = when the values are not an array, table or buffer.
(assert (deep-not= @{ :x (int/s64 1) } @{ :x (int/u64 1) }))
http://www.dtcms.com/a/585424.html

相关文章:

  • 05 kafka 如何存储较大数据记录
  • 使用Unity ASE插件设置数值不会生效的问题
  • 【ZeroRange WebRTC】WebRTC 信令安全:实现原理与应用(深入指南)
  • 关于Flutter与Qt for python 的一些技术、开源、商用等问题
  • 国外免费建站网站不用下载设计师培训心得
  • 深入解析 LeetCode 1572:矩阵对角线元素的和 —— 从问题本质到高效实现
  • Android Input ANR分析
  • Dify 添加 Google cloud 模型供应商
  • 大语言模型提示词技巧总结
  • 高职无人机应用技术专业职业发展指南
  • 网站流量软件银行门户网站建设
  • MySQL的CASE WHEN函数介绍
  • 逻辑方程结构图语言的机器实现(草稿)
  • 计算机组成原理---中央处理器
  • 合肥建设学校官方网站网站栏目规划图
  • windows11配置wsl安装ubuntu20.04
  • Go语言中的函数
  • 建瓯市建设局网站国内团购网站做的最好的是
  • XMSRC4392_VC1:4通道192KHz ASRC及768KHz SSRC音频采样率转换器产品介绍
  • 来宾绍兴seo网站托管方案手机怎么弄微信公众号
  • C 标准库 - <ctype.h>
  • Xshell效率实战:SSH管理秘籍(二)
  • 克隆整个macOS系统到新磁盘
  • 详解【限流算法】:令牌桶、漏桶、计算器算法及Java实现
  • Spring Cloud Config
  • 河南卫生基层系统网站建设企业资质查询系统官网
  • 临沂网站改版购买商标去哪个网站
  • 模块化并行清洗工装:实现规模化清洗的增效方案
  • Vue项目实战《尚医通》,首页医院组件的搭建,笔记09
  • 《新概念英语青少年版》Unit1-4知识点