美文网首页
Kotlin:基础语法学习(二)

Kotlin:基础语法学习(二)

作者: Coralline_xss | 来源:发表于2021-02-07 18:50 被阅读0次

    本篇内容清单如下:

    • 函数
    • 变量
    • 基本类型
    • 控制流

    一、基本语法

    1. 包定义与导入

    • 同 Java,在文件顶部声明:package(修饰符) 包名
    • 源文件的 所有内容(类、函数)都包含在 声明的 包内。
    • 若没有指明包名,则文件内容属于 无名字的 默认包。

    导入:

    • 导入包:import packageName
    • 若出现类名冲突,则可使用 as 关键字本地重命名消除歧义。【1】
    import org.example.Message
    import org.test.Message as TestMessage
    

    import 关键字使用场景:

    • 导入「类」
    • 导入 「顶层函数 及 属性」
    • 导入 在 「对象声明」 中声明的函数和属性;
    • 导入「枚举常量」

    2. 程序入口

    kotlin 应用程序的入口点是 main 函数。(虽如此,但是以下 main 无法再 AS 中识别。)

    fun main() { println("hello word !") }
    
    // 可识别运行的 main 方法
    companion object {
            @JvmStatic
            fun main(args: Array<String>) {
                println("hello word !")
            }
    }
    

    3. 函数

    • 声明:使用 fun 关键字。
    • 形式:fun 函数名(参数名: 类型, 参数名: 类型): 返回值类型 { // 函数体 } 。每个参数,必须有显式类型。
    • 调用:sum(1 + 2)

    一个加法函数的两种写法:

    // 1. 完整写法
    fun sum(a: Int, b: Int): Int {
      return a + b
    }
    
    // 2. 函数体仅含 单个表达式,并且 返回值 可 自动推断类型
    fun sum(a: Int, b: Int) = a + b
    
    // 3. 返回值无意义(类比 void),则 Unit 返回类型可省略
    fun printSum(a: Int, b: Int): Unit {  // =>  fun printSum(a: Int, b: Int) { ... }
       println("sum of $a and $b is ${a + b}")
    }
    

    以上为一般函数调用,当然还有其他函数类型写法与调用,存在一些不同。同函数相关的内容主要有以下这五点:

    • 函数声明
    • 函数参数
    • 函数返回值
    • 函数调用
    • 函数作用域

    与 Java 很大不同的内容点:

    • 默认参数 && 具名参数 && 可变参数
    • 中缀表示法
    • 局部函数(闭包)
    • 扩展函数
    • 高阶函数 && Lambda 表达式

    根据文档整理出来的导图(函数作用域后续文章还会继续说道)如下:


    Kotlin 函数相关概念总结

    [说明:星星 - 新概念且重要,问号 - 暂不理解,红旗 - 新概念但不重要。]

    备注:

    • 主构造函数很特别,参数可以使用 val 或 var 声明,但是普通函数不能用。次构造函数没啥大差别。
    class Person constructor() { }
    
    class Person constructor(name: String)
    
    class Person(name: String)
    
    class Person public constructor(name: String)
    
    class Person(name: String) {
        var children: MutableList<Person> = mutableListOf()
        // 次构造函数,必须要委托给 主构造函数
        constructor(name: String, parent: Person)  : this(name) {
            parent.children.add(this)
        }
    }
    

    4. 变量

    两种类型:

    • 只读变量,使用关键字 val 定义。只能为其赋值一次。
    • 可重新赋值的变量,使用关键字 var 定义。

    变量又可分为:

    • 顶层变量:在文件最顶部声明的变量
    • 属性与字段:类中或函数中声明与定义。
    val a: Int = 1 // 立即赋值
    val b = 2       // 自动推动出类型,可省略 参数类型
    // b = 3         // 重新赋值,编译器会报错
     
    var x = 5      // 自动推断类型
    x += 5
    

    二、基本类型

    在 Kotlin 中,也是 “一切皆为对象”。但有些类型 可以在运行时,表示为「原生类型值」,如 数字、字符以及布尔值。

    Kotlin 中的基本类型:

    • 数字:Byte、Short、Int、Long、Float、Double
    • 字符:Char
    • 布尔值:Boolean / true false
    • 数组:Array
    • 字符串:String
    1. 数字
    • Long、Float、Double 类型同 Java 一致,后面可带 L、f/F、D 。
    • Kotlin 中「无隐式拓宽转换」,如具有 Double 类型参数的函数,只能接收 Double 类型的值,而不能对 Float、Int 或其他数字值调用。
    • 若需要原生类型 对应的 可空引用泛型,如 Int 可空引用对应为 Int?,后者会把数字进行装箱。 [注:数字装箱不一定保留同一性。=== 判断同一性。 ]

    每个数字类型 都支持如下 转换函数:

    • toByte(): Byte
    • toShort(): Short
    • toInt(): Int
    • toLong(): Long
    • toFloat(): Float
    • toDouble(): Double
    • toChar(): Char
    2. 字符
    • 不能直接当做数字。
    • 字面值使用单引号 '1' 。
    3. 布尔
    • 同 java ,值 true 与 false 。
    • 布尔运算:|| 、 &&、 !
    4. 数组
    • 用 Array 表示,定义可 get 与 set 函数,可以转变为 []
    • 构建数组:arrayOf(1, 2, 3)
    • 原生类型数组:ByteArray、IntArray 等。
    5. 字符串
    • 用 String 表示。字符串是不可变的,元素访问,可用索引运算符访问:s[i]
    • 访问字符串:for (c in str) { } 、str[0]
    • 拼接字符串,可以使用操作符 +,但不建议,一般都使用 字符串模板 $原始字符串
    原始字符串
    • 原始字符串:使用三个引号 (""") 分解符,内部 无转义 且 包含换行以及任何其他字符。""" println("hello world!")""" 。另可默认 | 作为边界前缀。
    var text = """
        for (c in "foo") 
            print(c)
    """
    
    // 去除前导空格
    var text = """
      |Tell me and I forget.
      | Teach me and I remember.
    """.trimMargin() 
    
    字符串模板
    • 字符串字面值 可使用 模板表达式,以 美元符 $ 开头。
    • 单个变量,可省略花括号,如 i ;表达式,则使用{a + b} 。

    整理导入如下:


    Kotlin 基本类型汇总

    三、控制流

    同 Java 有些差别,Kotlin 控制类分为:

    • if
    • when
    • for
    • while

    以下仅整理不一致的点。

    if 表达式
    • 若为单个 if 表达式,则可以直接 返回值或 赋值给变量,但必须要有 else 分支。
    val max = if (a > b) a else b
    
    when 表达式
    • 取代了 C 语言的 switch 语句。
    • 分支条件,可以是单个变量,也可以是 某个表达式,只要满足条件,则执行该分支的内容。
    • 若 多个分支 处理方式一致,则可以将分支条件放在一起,用 , 隔开。
    val x = 3
    when (x) {
          1           -> print("x == 1")
          2,3         -> print("x > 1")
          "1".toInt() -> print("it's 1")
          in 1..10    -> print("x is in the range")
          !in 10..20  -> print("x is outside the range")
          is Int      -> print("x is Int type")
          else        -> print("none of above")
    }
    
    Break 与 Continue 标签
    • Kotlin 中任何表达式都可以使用 标签 来标记。标签的格式:@标识符
    • 函数嵌套,可返回到指定标签处。

    四、习惯用法

    五、编码规范

    六、DEMO 练习

    首先写一个 Java Demo,然后对比一下 Kotlin 的写法。具体内容为:一个 User Model 类,一个 UserManager 单例类,再加上 main() 入口函数调用(均是内部静态类写法)。

    这里面涉及到关于 kotlin 的内容点:

    • 变量声明
    • 函数声明
    • 空值与 null 检测
    • 类与对象
    • 单例类
    • 静态方法

    这是我之前学 kotlin 时,特别想知道如果 kt 来写,会是怎样的。当然对于 static 修饰的变量和方法,在 kt 中都是包裹在 compion object 中,称为「伴生对象」,这一点首次接触,感觉非常新奇。

    以下为 Java 实现:

    public class JavaDemo {
    
        public static void main(String[] args) {
            User user = new User();
            user.name = "cc";
            user.age = 24;
            user.address = "Shanghai";
    
            UserManager.getInstance().addUser(user);
            UserManager.getInstance().addUser(new User("kk", 25));
        }
    
        public static class UserManager {
    
            private static UserManager sInstance;
    
            private List<User> users = new ArrayList<>();
    
            public static UserManager getInstance() {
                if (sInstance == null) {
                    synchronized(UserManager.class) {
                        if (sInstance == null) {
                            sInstance = new UserManager();
                        }
                    }
                }
                return sInstance;
            }
    
            private UserManager() {}
    
            public void addUser(User user) {
                if (!users.contains(user)) {
                    users.add(user);
                }
            }
    
            public void addUsers(List<User> users) {
                if (!this.users.containsAll(users)) {
                    this.users.addAll(users);
                }
            }
    
            public void removeUser(User user) {
                users.remove(user);
            }
    
            public void removeByIndex(int index) {
                users.remove(index);
            }
    
            public void clear() {
                users.clear();
            }
        }
    
        public static class User {
            private String name;
    
            private int age;
    
            private String address;
    
            public User() {}
    
            public User(String name, int age) {
                this.name = name;
                this.age = age;
            }
    
            public String getName() {
                return name;
            }
    
            public void setName(String name) {
                this.name = name;
            }
    
            public int getAge() {
                return age;
            }
    
            public void setAge(int age) {
                this.age = age;
            }
    
            public String getAddress() {
                return address;
            }
    
            public void setAddress(String address) {
                this.address = address;
            }
        }
    }
    

    Kotlin 写法如下:

    import java.util.*
    
    class JavaVSKotlinDemo {
    
        companion object {
            @JvmStatic
            fun main(args: Array<String>) {
                val user = User()
                user.name = "cc"
                user.age = 24
                user.address = "Shanghai"
    
                UserManager.getInstance().addUser(user)
                UserManager.getInstance().addUser(User("kk", 25))
            }
        }
    
        class UserManager private constructor() {
    
            private val users = ArrayList<User>()
    
            fun addUser(user: User) {
                if (!users.contains(user)) {
                    users.add(user)
                }
            }
    
            fun addUsers(users: List<User>) {
                if (!this.users.containsAll(users)) {
                    this.users.addAll(users)
                }
            }
    
            fun removeUser(user: User) {
                users.remove(user)
            }
    
            fun removeByIndex(index: Int) {
                users.removeAt(index)
            }
    
            fun clear() {
                users.clear()
            }
    
            companion object {
                // 单例模式
                private var sInstance: UserManager? = null
                    get() {
                        return field ?: UserManager()
                    }
    
                @JvmStatic
                @Synchronized
                fun getInstance(): UserManager {
                    // synchronized(UserManager::class.java)
                    return requireNotNull(sInstance)
                }
            }
        }
                                                                         
        class User constructor() {
            var name: String? = null
    
            var age: Int = 0
    
            var address: String? = null
    
            constructor(name: String?, age: Int) : this() {
                this.name = name
                this.age = age
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:Kotlin:基础语法学习(二)

          本文链接:https://www.haomeiwen.com/subject/ixucaktx.html