Kotlin入门(17)等式判断的情况

话说等式可是编程语言最基本的表达式之一,不管哪种高级语言,无一例外都采用双等号“==”判断两个变量是否相等;就算是复杂的对象,在Java中也可通过equals函数判断两个实例是否相等。按理说这些能够满足绝大多数场合的要求了,那么Kotlin又给等式判断加入了哪些新概念呢?下面就让我们好好探讨一下具体业务中的等式判断。

结构相等
基本数据类型如整型、长整型、浮点数、双精度数、布尔型,无论是在C/C++还是在Java抑或是在Kotlin,都使用双等号“==”进行两个变量的相等性判断。至于字符串类型,则比较特殊,因为最早C语言是在内存中开辟一块区域,利用这块区域存储字符串,并返回一个字符指针指向该区域的首地址,此时如果对两个字符指针进行“==”运算,结果是比较两个指针指向的地址是否相等,而非比较两个地址存储的字符串是否相等;所以C语言判断两个字符串是否相等,用到的是strcmp函数;Java参考了C++,虽然不再使用字符指针,而使用String类型表示字符串,但是Java判断两个字符串是否相等,采用了equals函数,从一个函数换成另一个函数,仍然是换汤不换药,没有本质上的改变。
现在Kotlin痛定思痛,决心要革除这种沿袭已久的积弊,反正都把字符串当作跟整型一样的基本数据类型了,何不直接统一相关的运算操作符?因此,既然整型变量之间使用双等号“==”进行等式判断,字符串变量之间也能使用双等号“==”来判断;以此类推,判断两个字符串是否不相等,通过不等运算符“!=”即可直接辨别。从Java到Kotlin,改变后的等式判断表达式如下表所示:
判断两个字符串是否相等 strA.equals(strB) -> strA == strB
判断两个字符串是否不等 !strA.equals(strB) -> strA != strB

下面是个Kotlin判断字符串相等性的代码例子:

    val helloHe:String = "你好"
    val helloShe:String = "妳好"
    btn_equal_struct.setOnClickListener {
        if (isEqual) {
            tv_check_title.text = "比较 $helloHe 和 $helloShe 是否相等"
            //比较两个字符串是否相等的Java写法是 helloHe.equals(helloShe)
            val result = helloHe == helloShe
            tv_check_result.text = "==的比较结果是$result"
        } else {
            tv_check_title.text = "比较 $helloHe 和 $helloShe 是否不等"
            //比较两个字符串是否不等的Java写法是 !helloHe.equals(helloShe)
            val result = helloHe != helloShe
            tv_check_result.text = "!=的比较结果是$result"
        }
        isEqual = !isEqual
    }

其中“==”的判断结果如下面左图所示,“!=”的判断结果如下面右图所示。

推而广之,不单单字符串String类型,凡是Java中实现了equals函数的类,其对象实例均可在Kotlin中使用“==”和“!=”进行等式判断。这种不比较存储地址,而是比较变量结构内部值的行为,Kotlin称之为结构相等,意即模样相等,通俗地说就是一模一样。

引用相等
有时候仅仅判断两个变量值是否相等,并不足以完成某种一致性判断,现实生活中还有更严格的真伪鉴定需求,比如真假美猴王、文物的真品与赝品、兰亭集序的真迹与摹本等等。倘若按照结构相等的判断标准,复制品和真品在外观上没有区别,毫无疑问就是相等的。但这个相等的结果明显与大众的认知相悖,因为真品是唯一的,复制品再怎么逼真也不可能与真品等价,所以结构相等并不适用于真伪鉴定,如何判断真伪需要另一种由内而外全部相等的判断准则,该准则叫做引用相等,意思是除了值相等以外,还要求引用的地址(即存储地址)也必须相等。
在Kotlin中,结构相等的运算符是双等号“==”,那么引用相等的运算符便是三个等号“===”,多出来的一个等号表示连地址都要相等;结构不等的运算符是“!=”,相对应的,引用不等的运算符是“!==”。不过在大多数场合,结构相等和引用相等的判断结果是一致的,下面列出常见的几种等式判断情景:
1、对于基本数据类型,包括整型、浮点数、布尔型、字符串,结构相等和引用相等没有区别;
2、同一个类声明的不同实例,如果不是每个属性都相等,则其既是结构相等,又是引用相等;
3、同一个类声明的不同实例,如果equals校验的每个属性都相等(譬如通过clone方法克隆而来),则其结构相等,但引用不等;
为详细说明以上的等式判断,下面给出具体的代码例子,利用系统自带的时间Date类演示一下结构相等和引用相等的区别:

    val date1:Date = Date()
    val date2:Any = date1.clone() //从date1原样克隆一份到date2
    btn_equal_refer.setOnClickListener {
        when (count++%4) {
            0 -> {
                tv_check_title.text = "比较 date1 和 date2 是否结构相等"
                //结构相等比较的是二者的值
                val result = date1 == date2
                tv_check_result.text = "==的比较结果是$result"
            }
            1 -> {
                tv_check_title.text = "比较 date1 和 date2 是否结构不等"
                //结构不等比较的是二者的值
                val result = date1 != date2
                tv_check_result.text = "!=的比较结果是$result"
            }
            2 -> {
                tv_check_title.text = "比较 date1 和 date2 是否引用相等"
                //引用相等比较的是二者是不是同一个东西,即使克隆的一模一样也不是一个东西
                val result = date1 === date2
                tv_check_result.text = "===的比较结果是$result"
            }
            else -> {
                tv_check_title.text = "比较 date1 和 date2 是否引用不等"
                //引用相等倒过来便是引用不等
                val result = date1 !== date2
                tv_check_result.text = "!==的比较结果是$result"
            }
        }
    }

上述代码的date2从date1克隆而来,所以二者的值是完全一样的,区别仅仅是存储的地址不同。接着使用双等号“==”以及“!=”进行结构判断,运算结果为相等,详细结果如下图所示。

继续使用三等号“===”以及“!==”进行引用判断,运算结果却是不等,详细结果如下图所示。

以上的实验结果,证明了引用相等校验的是变量的唯一性,而结构相等校验的是变量的等值性。

原文地址:https://www.cnblogs.com/aqi00/p/9665551.html

时间: 2024-10-13 04:45:28

Kotlin入门(17)等式判断的情况的相关文章

iOS开发入门——17条 Swift 最佳实践规范(下)

文章来源:http://www.zretc.com/technologyDetail/433.html 承接上文:iOS开发入门--17条 Swift 最佳实践规范(上) 9.单例(Singletons) 在Swift中单例是很简单的: class ControversyManager { static let sharedInstance = ControversyManager()} Swift 的 runtime 会保证单例的创建并且采用线程安全的方式访问. 单例通常只需要访问"share

Problem C: 【递归入门】组合+判断素数

Description 已知 n 个整数b1,b2,…,bn 以及一个整数 k(k<n). 从 n 个整数中任选 k 个整数相加,可分别得到一系列的和. 例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为: 3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34. 现在,要求你计算出和为素数共有多少种. 例如上例,只有一种的和为素数:3+7+19=29. Input 第一行两个整数:n , k (1<=n<=20,k&

Kotlin入门(32)网络接口访问

手机上的资源毕竟有限,为了获取更丰富的信息,就得到辽阔的互联网大海上冲浪.对于App自身,也要经常与服务器交互,以便获取最新的数据显示到界面上.这个客户端与服务端之间的信息交互,基本使用HTTP协议进行通信,即App访问服务器的HTTP接口来传输数据.HTTP接口调用在Java代码中可不是一个轻松的活,开发者若用最基础的HttpURLConnection来编码的话,至少要考虑以下场景的处理:1.HTTP的请求方式是什么,是GET还是POST还是PUT还是DELETE?2.HTTP的连接超时时间是

Flask快速入门(17) — flask_session

Flask快速入门(17) - flask_session 作用:将默认保存的签名cookie中的值,保存到 redis/memcached/file/Mongodb/SQLAlchemy 安装:pip install flask-session 使用1: from flask import Flask,session from flask_session import RedisSessionInterface import redis app = Flask(__name__) conn=r

iOS开发入门——17条 Swift 最佳实践规范(上)

文章来源:http://www.zretc.com/technologyDetail/432.html 前言 这篇IOS开发入门文章是我根据在 SwiftGraphics 工作时的一系列笔记整理出来的.文中大多数建议是经过深思熟虑的,但仍可以有其他类似的解决方法.因此,如果其他方案是有意义的,这些方案会被添加上去. 这个最佳实践不是强加或者推荐 Swift 在程序.面向对象或者函数风格上的应用.更重要的是,这里要讲述的是务实的方法.如有需要的话,某些建议可能会集中在面向对象或者实用的解决方法.

Kotlin入门

转载自:https://www.cnblogs.com/jaymo/articles/6924144.html 创建类的实例 要创建一个类的实例,我们就像普通函数一样调用构造函数: 1 2 3 val invoice = Invoice() val customer = Customer("Joe Smith") 注意 Kotlin 并没有 new 关键字. 继承 在 Kotlin 中所有类都有一个共同的超类 Any,这对于没有超类型声明的类是默认超类 1 class Example

挨踢部落坐诊第六期:机器学习如何判断突发情况?

活动说明:挨踢部落是为核心开发者提供深度技术交流,解决开发需求,资源共享的服务社群.基于此社群,我们邀请了业界技术大咖对开发需求进行一对一突破,解除开发过程中的绊脚石.以最专业.最高效的答复为开发者解决开发难题. 话题关键词:机器学习/IDEA/ vSphere /云计算/ SDK埋点/技术管理 部落阵容:51CTO社群智囊团 面向对象:Java工程师.移动开发开发工程师.IT运维.数据分析师 参与方式:加入51CTO开发者QQ交流群(群号312724475),有任何技术问题,在群里提问,或发给

判断录取情况

某校计算机专业今年录取研究生的要求是:政治.英语每门课成绩不低于60分,数学和专业课不低于90分,总成绩不低于310分.并且规定:在满足单科以及总成绩最低要求的基础上,350分以上(含350分)为公费(Gongfei),310分~349分为自费(Zifei). 请编程判断考生的录取情况. N=int(raw_input())for i in range(N):    a,b,c,d=map(int,raw_input().split())    s=a+b+c+d    if  a<60 or

Kotlin入门(12)类的概貌与构造

上一篇文章提到泛型函数appendString是在类外面定义,这不免使人疑惑,类里面又该怎样定义成员函数呢?为解答这个疑问,接下来的几篇文章将好好描述一下Kotlin如何操作类及其对象,本篇文章先对类的定义进行说明并加以运用. 之前我们已经多次见过的类MainActivity,在Java代码中该类的写法如下所示: public class MainActivity extends AppCompatActivity { } 而对应的Kotlin代码是下面这样的: class MainActivi