7. swift & kotlin 的字符串常用操作

值类型

swift 的字符串是值类型,这点和 kotlin 是不一样的,kotlin 来自于 java,所以和java 一样,是对象类型。

swift 并不是每次赋值字符串都会发生拷贝,只有新的对象发生改变的时候才会发生值拷贝

可变与不可变

swift 的 String 类型可变与不可变取决于是否可以定义的字段

let str = "test" // 不可变
var str2 = "test" // 可变

感觉很完美的继承了 swift 定义的风格
kotlin 是 Jvm 语言,所以所有的字符串都是不可变的

val str1 = "test" // str1 指向的对象不可变
var str2 = "test" // str2 指向的对象可变

因此, Swift 的 字符串可以这样操作

var str = "test"
str.append("test")

kotlin 是没有这样方法的,只能生成一个新的字符串赋值给新的对象

var str = "test"
str = str + "test"

当然,kotlin 直接使用 StringBuilder 就能或者一致的体验了

var str = StringBuilder("test")
str.append("test")

总得来说,swift 这个地方定义要更高一筹

继续阅读“7. swift & kotlin 的字符串常用操作”

6. swift & kotlin之字符串

它们字符串定义和实现都是一样的

swift 定义

let str = "我是一个串"
let str = String("我是一个串")

kotlin 定义

val str = "我是一个串"
val str = String("我是一个串")

但是其他扩展用法来说 swift 更强大,我也觉得更好用

替换字符

swift

let number = 1
let str = "我是 \(number)条狗"

kotlin

var number = 1
var str = "我是 $number 条狗"

Groovy

def number = 1
def str = "我是 $number 条狗"

typescript

const number = 1
const str = `我是 ${number} 条狗`

通过对比可以发现,天下语言大同,唯独 typescript 搞特殊。
但是这里面的使用方法我更喜欢 kotlingroovy 的写法

继续阅读“6. swift & kotlin之字符串”

3. swift & kotlin 的 Optional

swift

swift 中的 Optional 定义是这样的

let str : String? = nil

拆开就是这样拆开

print(str!)

同时语言级别提供几个语法糖,比如可以这样

if let myStr = str {
    // 这里就不用解开了,相当于 let 给你解开了
    print(myStr.count)
}

实际上的实现呢是通过系统官方的一个 Optional 类来实现的,加上 ? 号只是方便定义而已,比如一开始的代码也可以这样写

let str : Optional<String> = "112"

有没有发现这个和 Java 的 Optional 巨相识

后面的操作其实也就是隐式调用这个类的方法而已,不展开了,具体自己看源码。

kotlin

回到 kotlin 这里,kotlin 其实也有类似的定义,也不能说类似,几乎差不多,但是更强大

定义:

val str: String? = "11"
if (str != null){
    // 注意这里是不需要像swift那么麻烦的,需要赋值,这里kt会自动推断,不需要自己拆包
    print(str.lenght)
}

拆包:

// 嗯,kt 的拆包是两个叹号,比 swift 多一个
println(str!!.length)

高级组合拳:
kotlin 可以使用各种作用域函数进行快速的操作,这点比 swift 要强很多

根据 kotlin 的源码实现,其实 swift 其实也是可以实现这样的方法的,但是官方就是没有,我觉得很诡异

// 通过这个方式,就能直接把一个可选的值变成非空的it,然后进行操作,这边要比 swfit 强
str?.let{ println(it) }

而且这样的快速操作方法,kotlin 有五个,分别是 let,run,with,applyalso

takeIftakeUnless 不属于这个类别

typescript作为前端的希望,不好意思,它没有这个东西😀

继续阅读“3. swift & kotlin 的 Optional”

9月是个好月份

原版

  • 9.2 Nvidia RX30x0 显卡发布,4k游戏可及
  • 9.3 Intel正式发布了代号Tiger Lake的第11代低功耗酷睿处理器,牙膏挤爆
  • 9.9 Galaxy Z Fold2 5G 国内发布
  • 9.9 android 11 正式发布,同月各大国内厂商将会推送,所以要适配了
  • 9.15 苹果秋季发布会
  • 9.26 楼下喜茶要开了[狗头]

NVIDIA-GeForce-RTX-3080-Graphics-Card-scaled

Samsung-Galaxy-Fold-2-Concept-Ben-Geskin

ac2ab1c0-f1e7-11ea-aecc-6ddca9711160

苹果版本

  • ✅ 9.2 Nvidia RX30x0 显卡发布,4k游戏可及
  • ✅ 9.3 Intel正式发布了代号Tiger Lake的第11代低功耗酷睿处理器,牙膏挤爆
  • ✅ 9.9 Galaxy Z Fold2 5G 国内发布
  • ✅ 9.9 android 11 正式发布,同月各大国内厂商将会推送
  • ☑️ 9.15 苹果秋季发布会
  • ☑️ 9.26 楼下喜茶要开了[狗头]

欢迎补充[狗头]

4. swift & kotlin 元组

对于 swift 来说,这就是个系统帮你快速创建的类,主要你想打包几个字段的时候非常好用,也用不着为了打包定义几个类。

定义代码如下

let error = (1,"你就是错了",1,1,22,3,3,3,3,3)
print(error)

这个元祖里面是不限制数量,同时也支持给字段命名

let error = (code: 1, message: "错了就是错了")
print(error)
//output  (code: 1, message: "你的名字")

支持打包当然也直接拆包

let error = (code: 1, message: "错了就是错了")
let (code , message) = error
print("code : \(code),message \(message)")
//out code : 1, message 错了就是错了

这货在 kotlin 里面也有,但是没有那么强大

val error = Pair(1,"错了就是错了")
val error2 = Triple(1, "错了就是错了","我是第三个")
println("first : ${error.first}, second : ${error.second}")
println(error)

// output
// first : 1, second : 错了就是错了
// (1, 错了就是错了)

kotlin 是通过 PairTriple 这两个类实现的,是需要手动调用,而且目前最多支持 3 个,不支持命名字段,在我看来就是有语言加成的类,当然它也支持解包

val (code,message) = error
println("code : $code, message : $message")

但是和 swift 不同的是,kotlin 中元组的值是一定不可变的,比如 swfit 中

var error = (code: 1, message: "错了就是错了")
error.code = 1

这样是没问题的,但是 kotlin 因为本质就是个类,它的定义决定了是不能变的

public data class Pair<out A, out B>(
    public val first: A,
    public val second: B
)

所以这样操作是不行

var error = Pair(1, "错了就是错了")
error.first = 1

总结就是,苹果爸爸技高一筹,kotlin 因为要兼容 Java 语言做了很多妥协

5. swift & kotlin Optional 的用途

用了 optional 是不是不会为空呢?

这个显然不用问的,肯定是能够为空的,难道程序还能拦住人不成?
比如这样的代码

func jump(str : String){}
jump(nil!) // 我这样写你能奈我何?

那么这个东西的用处是什么?

声明不为空

为了明确各自的边界
比如 Java 的一个方法

void jump(String name){    
    if(name.lenght != 0){
        // do
    }
}

如果外部传入空值怎么办?
第一波尝试,增加 NouNull 注解

void jump(@NouNull String name){    
    if(name.lenght != 0){
        // do
    }
}

但是注解只是编译提醒,人家不看编译提醒还是传了空怎么办?
那就第二波修改,null 检查

void jump(@NouNull String name){    
    if (name == null){
        throw new IllegalArgumentException("参数不能为空");
    }
    if (name.lenght != 0){
        // do
    }
}

第二波修改明显就能够防止问题的,但是如果让你每个方法都这样写一遍,是不是感觉很累?

kotlin 简化了这种写法

fun jump(name: String) {
    if(name.isNotEmpty()){
       //do  
    }
}

当你尝试这样调用的时候 jump(null) 会编译直接报错,因为这里声明的不是可选类型,不能为空。
如果你这样写 jump(null!!)那就会运行时候报错,自动检查空

swift 也是一样

func jump(name: String) {
    if ( name.lenght != 0){
       //do  
    }
}

减少判空的噪音

同样的java代码,要判空需要这样写

void jump(String name){    
    if(name != null && name.lenght != 0){
        // do
    }
}

但是 kotlin 只需要这样

fun jump(name: String?){    
    if(name?.lenght != 0){
        // do
    }
}

swift 也是这样

func jump(name: String?){    
    if(name?.lenght != 0){
        // do
    }
}

其实我觉得最方便的时候是有个类需要接受一个 callback
这个 callback 是可以为空的,然后你就需要每个使用的地方都加个空判断,就比如下面这样的代码

class PushManager{
    private PushCallback pushCallback;
    
    private void onPush(){
        if(pushCallback != null){
            pushCallback.onGetPushData();
        }
    }
}

但是如果换成 kotlin 编写的话就非常愉悦了

class PushManager{
    private var pushCallback : PushCallback?;
    
    private onPush() {
        pushCallback?.onGetPushData();
    }
}

简直和不用写判空一样,这样减少了很多代码噪音,让开发人员更加专注于编写代码本身

2. swift & kotlin 变量可变与不可变

两边都有可变和和不可变的定义就是名字不太一样

swift 是这样

let 不变 = 1
var 可变 = 1

kotlin 是这样

val 不可变 = 1
var 可变 = 1

其实就是对应 Java 的

final int 不可变 = 1;
int 可变 = 1;

因为平常开发中不可变用的其实比较多,java 这个天天敲 final 的确让人受不了,kotlin 简写这个还是挺好的

这里插一下别的语言

typescript 是这样

const 不可变 = 1
var 可变 = 1

就你不一样?作为现代语言能不能统一一下????

1. swift & kotlin数据类型

基本数据类型

类型 大小(字节数) 区间值(自己算,不写)
Int8 1
UInt8 1
Int32 4
Int64 8
UInt32 4
UInt64 8
Float 4
Double 8

无符号类型 kt 其实也有,只不过在1.4版本的实验特性上

Int 类型和 Kotlin 不一样的,Int类型 Swift 是根据平台来的,这点和 C 倒是挺像的,Kotlin 是JVM语言,就是表示这货不同平台都是那么多位的,我觉得这个设计比Swift更好

Bool 类型

其实就是 true or false,别说 kt,java 都用几百年了

let isMy: bool = false

if(isMy){
    print("你的")
}else{
    print("我的")
}

kotlin 实现其实也差不多,就是名字不太一样,人家是boolean

val isMy: Boolean = false
if (isMy) {
    print("你的")
} else {
    print("我的")
}

类型别名

typealias AudioSimple = Int
let b : AudioSimple = 1

kotlin 是把这个代码把 let 改为 val 放到 kotlin 直接就可以运行,毫无违和感

typealias AudioSimple = Int
val b : AudioSimple = 1