Kotlin是Android的最新开发语言;
Swift是iOS的最新开发语言;
二者语法很像, 下面就对比一下。
Kotlin中文网站: https://www.kotlincn.net/docs/reference/basic-syntax.html
按官方文档顺序说明:
功能 | Kotlin | Swift | 说明 |
定义包 | package com.*.* 实例:pacakge com.brycegao.test | import * 实例: import UIKit | 1、Kotlin声明定义包跟Java相同,包名必须是小写字母; 2、Swift引用库时使用import关键字。 |
引用类 | import *.*.* 实例:import java.util.* | 只需引用库 | Kotlin跟Java相同, Swift不需要引用类、只需要引用库即可; |
定义函数 | fun sum(a: Int, b: Int): Int { return a + b } 如果函数体只有一行代码,可以简写函数。 fun sum(a: Int, b: Int): Int = a + b 调用方法: sum(1, 2) | func sum(label1 a: Int, label2 b: Int)->Int { return a + b} 调用方式: sum(lable1: 1, label2: 2) | 1、Kotlin使用fun作为函数关键字; 2、func使用func作为函数关键字; 3、Kotlin使用:分隔参数和返回值类型; 4、Swift使用->分隔参数和返回值类型; |
可变参数 | var关键字 举例: var a: Int = 1 | var关键字 举例: var a: Int = 1 var b: Int //可以不赋值 | Kotlin和Swift都是用var关键字声明可变参数,参数值可修改且声明时不必赋值。 |
常量参数 | val关键字 举例: val a: Int = 1 | let关键字 举例: let a: Int = 1 | 声明时必须要赋值,而且参数值不可改 |
注释 | //一行注释 /*多行注释*/ | //一行注释 /*多行注释*/ | Swift和Kotlin注释方法相同 |
字符串模板 | var a = 1 var s1 = “a is $a” //用双引号包含起来 $后面跟着参数 a = 2 val s2 = “${s1.replace(“is”, “was”)}, but now is $a” | var a = 1 var s1 = "a is \(a)" a = 2 let s2 = "\(s1.replacingOccurrences(of: "is", with: "was")), but now is \(a)" | 1、Kotlin使用$和{}声明参数或者调用函数; 2、Swift使用\()包含参数; |
转义 | val s = “my name is \”zhangsan\” ” | let s = “my name is \”zhangsan\” “ | 使用\转义 |
if条件表达式 | fun maxOf(a: Int, b: Int): Int { if (a > b) { return a } else { return b } } 或者 fun maxOf(a: Int, b: Int): Int = if (a > b) a else b | func maxOf(label1 a: Int, label2 b: Int)->Int { if a > b { return a } else { return b } } | if条件为真则进入函数体,为假进入else函数体 |
空 | null | nil | |
可空值参数 | 在类型关键字后加问号,例如 var a: Int? = null | var a: Int? = nil | 都使用问号表示参数可能为空 |
数组 | val arr1 = listOf("apple", "banana", "kiwi") val arr2 = byteArrayOf(1, 2, 3, 4) val arr3 = IntArray(5) val arr4 = FloatArray(5) val arr5 = DoubleArray(5) val arr6 = BooleanArray(5) | let array1 =[1, 2, 3, 4, 5] //Int型数组 let array2: Array<Int> = Array() //声明并定义了Int型数组 let array3:[Int] =[] //声明并实例化Int型数组 let array4 = Array(repeating: 0, count: 5) //数组有5个值,全是0 | 1、Kotlin必须使用函数来定义数组; 2、Swift定义数组更多样灵活; |
遍历数组 | for(item in arr1){ println(item) } //或 for(i in arr1.indices) { println(arr1[i]) //通过下标取值 } | for item in array1 { print(item) } //或 var i = 0 while i < array1.count { print(array1[i]) i += 1 } | 1、都支持for-in循环; 2、通过下标遍历; |
区间操作符 | ..为区间操作符,等价于[] 举例: for(i in 1..5) { print(i) //输出1,2,3,4,5 } for (i in1..10 step 2) { | …为区间操作符,等价于[]; ..<等价于[) for i in 1...5 { print(i) //输出1,2,3,4,5 }
for i in 1..<5 { print(i) //输出1,2,3,4 } | Kotlin支持设置步长step, Swift步长只能是1. |
语句分隔符 | 使用分号,默认不用写 var o1 = 1; //一行只能写一条语句 | var o1 = 1; var o2 = 2 | 都是用分号分隔,默认不用写 |
空返回值 | Unit //返回值为空 fun method1() {
} | Void func method() -> Void {
} //或 func method1() {
} | 函数返回值为空,可以省略返回值类型,或者使用Unit、Void关键字 |
类 | //默认不支持继承,等同于Java的final class class SomeClass {
}
//使用open关键字,表示可继承的类 open class BasicClass constructor(name: String) { var value: String
init { value = name //主构造函数 } //次构造函数必须调用主构造函数 constructor(age: Int, name: String): this(name) { //函数体 } //...属性方法 }
class Ext: BasicClass("basic") { //...属性、方法 } | class BasicClass { var name: String? var age: Int?
init(param: String?) { //构造函数 name = param print("调用构造函数1 \(name)") }
convenience init(age param1: Int, name param2: String) { self.init(param: param2) age = param1 } //...属性和函数
deinit { //析构函数 } } let obj1 = BasicClass(age: 10, name: “zhangsan") //派生类 class Ext: BasicClass { //...属性和函数 } | 1、Kotlin类默认不支持继承,必须要用open关键字表示可继承; 2、Swift默认支持继承; 3、Kotlin使用contructor定义构造函数,且分为主构造和次构造函数,次构造函数必须调用主构造函数; 4、Kotlin使用this调用其它构造函数; 5、Swift使用this调用其它构造函数,但必须添加convenience关键字; 6、Swift使用init作为构造函数,deinit作为析构函数; |
结构体 | 不支持 | struct关键字 值类型 | Swift类和结构体的区别是引用类型、值类型 |
自增或自减 | vara1 = 1 | var a = 1 a += 1 a -= 1 | 1、Kotlin支持++和—; 2、Swift不支持++和—, 但支持+=和-+。 |
控制流 | var x = 10 when(x) { //不用break关键字 0, 1 -> { //使用逗号分隔,当x等于0或1时执行 print("第一条语句") print("第二条语句") } 2 -> { //只有1个值时 print("值等于2") } in 3..10 -> { //区间操作符,关键字是in和..值为[3,10] print("区间操作符") } !in 11..20 -> { //值不在[11,20]范围内
} else -> { //条件都不符合,默认处理 } } | var a = 100 switch a { case 0,1: //多个条件 print("第一条语句") print("第二条语句") case 2: //一个条件 print("值等于2") case 3...10: //区间操作符 print("区间操作符") case 10...1000 where a%10==0: //添加where条件判断条件 print("执行where语句") default: print("默认处理") } | 1、Kotlin使用when作为条件判断关键字,不用break关键字; 2、Swift使用switch关键字作为分支判断关键字; |
if | vara = 1 | var a = 1 var b = 2
var max: Int if a > b { max = a } else { max = b } | Kotlin和Swift的if语句逻辑一样,区别是Swift if语句不需要括号 |
非空操作符 | vals1 = "this is a string" Kotlin使用?:作为操作符,如果前面值非空则等于前面的值, 否则取后面的值 | let s1 = "this is a string" let s2: String? = nil let ret1 = s1 ?? "default" //this is a string let ret2 = s2 ?? "default" //default | 1、Kotlin使用?:作为操作符取非空值; 2、Swift使用??作为操作符取非空值; |
标签 | 标识符后加@, 可以作为代码跳转的地方;语法类似于C语言的goto。 loop@ for (i in 1..100) { for (j in 1..100) { if (……) break@loop } } | 不支持 | 1、Kotlin使用的分支跳转语法; 2、早就被淘汰的语法,影响代码整体逻辑; 不建议使用。 |
接口 | interface关键字 | protocol关键字 | 不用实现函数体 |
内部类 | inner关键字, 内部类访问外部类时持有引用。实例:super@Outer open class Foo { open fun f() { println("Foo.f()") } open val x: Int get() = 1 //只读属性 }
class Bar : Foo() { override fun f() { /* …… */ } override val x: Int get() = 0
inner class Baz { fun g() { super@Bar.f() //调用 Foo 实现的 f() println(super@Bar.x) //使用 Foo 实现的 x的 getter } } } | class Ext: Basic { override func method() { print("Ext class method") }
//内部类不能访问外部类 class Baz { func g() {
} } } | 1、Kotlin内部类持有外部类的引用,但是语法有区别。 2、Kotlin支持覆盖方法和属性; 3、Swift支持覆盖方法,不支持覆盖属性; 4、Swift内部类不能访问外部类的方法、属性; 5、都使用override关键字覆盖方法; |
单例 | Kotlin不支持静态类型,使用伴生对象。 使用私有构造函数并添加同步锁,类不能被继承; class SingleTon private constructor(str: String){ | 使用static关键字 final class SingleTon { //单例类的属性 var name: String var age: Int
private init() { name = "" age = 0 print("SingleTon init is called") }
static let sInstance = SingleTon() } | 1、构造函数声明为私有函数,外部类无法实例化; 2、Kotlin需要添加同步锁synchronized, Swift不需要添加同步锁; 3、Kotlin使用伴生对象声明静态属性, Swift使用static声明静态属性; |
权限 | private意味着只在这个类内部(包含其所有成员)可见; protected——和 private一样 +在子类中可见。 internal ——能见到类声明的 本模块内的任何客户端都可见其 internal 成员; public ——能见到类声明的任何客户端都可见其 public 成员。 | open 可以其它作用域被访问、继承 public可以访问自己模块中源文件里的任何实体,别人也可以通过引入该模块来访问源文件里的所有实体。 internal可以访问自己模块中源文件里的任何实体,但是别人不能访问该模块中源文件里的实体。 fileprivate文件内私有,只能在当前源文件中使用。 private只能在类中访问,离开了这个类或者结构体的作用域外面就无法访问。 | |
扩展 | 扩展方法: fun类名.方法名(参数…):返回值类型 { 函数体 } //扩展方法 fun String.size(): Int { return this.count() } var str = "this is a string" print(str.size()) 扩展属性:val或var类名.属性名: 类型 var String.testNum: Int get(): Int { return this.count() } set(value) { print("测试") } | extension关键字,作用域是整个模块 //仅支持扩展方法,不支持扩展属性 extension String { func testMethod() { print("extension testMethod") } } var str = "this is a string" str.testMethod() | 1、Kotlin支持扩展属性和方法; 2、Swift支持扩展方法,但不能扩展属性; 3、Kotlin不需要关键字, Swift使用extension关键字; |
基类 | Any,所有类的基类 | AnyClass | 1、Kotlin使用Any作为基类,类似于Java的Object; 2、Swift有Any、AnyObject和AnyClass,所有类的基类是AnyClass。3、泛型和基类派生类引用会用到。 |
数据类 | data class User(var id: Int, var name: String) var user: User = User(1, "zhangsan") //实例化 var (id, name) = user //取值 user.name = "lisi" print("${user.component1()} ${user.component2()}") //1 lisi print(" ${user.id} ${user.name}") //1 lisi | 不支持 | 1、Kotlin使用data class关键字声明数据类,即类只有属性,不需要实现自定义函数; 2、Swift用class实现数据类; |
泛型 | classBox<T>(t:T) { varobj = Box(1) fun <T> chkType(content:T) { | class A<T> { var value: T init(param: T) { value = param } } var obj = A(param: 1) print(obj.value) //输出1 func testType<T>(content: T) { if content is Int { print("整型") } else if content is Float { print("浮点型") } else {
} } | Kotlin和Swift的泛型声明方式类似,都是<T>格式,泛型也可以继承于某类例如<T: String> |
枚举 | enum classDirection { varenum1 = Direction.EAST | enum Orientation: Int { case NORTH = 0 case SOURTH case WEST case EAST }
var value: Orientation = .EAST print(value.rawValue) //输出3 | 1、Kotlin声明枚举的语法跟Java类似; 2、Swift声明枚举的每个值都带前缀case; |
接口 | interface Base { fun print() }
class BaseImpl(val x: Int) : Base { override fun print() { print(x) } } | protocol Base { func testMethod() }
class BaseImple: Base { var age: Int? init(x: Int) { age = x }
func testMethod() { print(" testMethod \(age)") } } var obj = BaseImple(x: 10) obj.testMethod() | 1、Kotlin使用interface关键字声明接口; 2、Swift使用protocol关键字声明接口; 3、冒号实现一个或若干个接口; |
类型转换 | is as !is as?关键字 | is as as? as! | 类型转换关键字,用法类似; 区别是as!可能抛异常。 |
相等性 | 3个等号和2个等号 | 3个等号和2个等号 | 1、 ===表示地址相同; 2、==表示值相等,即equals方法为真; |
注解 | 在类名、函数名同行添加注解 实例:class Tests { //将 @Rule 注解应用于属性 getter @get:Rule val tempFolder = TemporaryFolder()
@Test fun simple() { val f = tempFolder.newFile() assertEquals(42, getTheAnswer()) } } | 一般不使用 例如app的入口类是@UIApplicationMain | 1、Kotlin的注解方法有点特别,是在当前行添加; 2、Swift很少使用注解; |