Kotlin学习笔记

---2017-11-21---

Kotlin中的when可以先什么都没有,然后再做操作.主要用于取代 if else if 然后再else这样的代码. if (tv_loan_choose.isEmpty()) { Methods.showToast(string.uc_choose_loan_period) } else if (et_loan_amount.isEmpty()) { Methods.showToast(string.uc_input_loan_amount) } else { submitLoanInfo(tv_loan_choose.trimText(), et_loan_amount.trimText()) }

改动后如下:

when { tv_loan_choose.isEmpty() -> Methods.showToast(string.uc_choose_loan_period) et_loan_amount.isEmpty() -> Methods.showToast(string.uc_input_loan_amount)

else -> submitLoanInfo(tv_loan_choose.trimText(), et_loan_amount.trimText())

}

---2017-11-21---

---2017-09-29--- http://beust.com/weblog/2015/10/30/exploring-the-kotlin-standard-library/ 关于Kotlin标准库中的also(),let(),with(),apply()等函数

apply()-->就是总是返回自己调用者自己 Intent it = new Intent(xx) it.putExtra(aa) it.putExtra(xx) it.putExtra(xx) it.apply(putExtra(xx)).apply(putExtra(xx)).apply(putExtra(xx))

let() let() is a scoping function: use it whenever you want to define a variable for a specific scope of your code but not beyond. It’s extremely useful to keep your code nicely self-contained so that you don’t have variables “leaking out”

DbConnection.getConnection().let { connection ->
}
// connection is no longer visible here

let() can also be used as an alternative to testing against null:

val map : Map<String, Config> = ...
val config = map[key]
// config is a "Config?"
config?.let {
    // This whole block will not be executed if "config" is null.
    // Additionally, "it" has now been cast to a "Config" (no question mark)
}

with() with() is convenient when you find yourself having to call multiple different methods on the same object. Instead of repeating the variable containing this object on each line, you can instead “factor it out” with a with call

val w = Window()
with(w) {
  setWidth(100)
  setHeight(200)
  setBackground(RED)
}

---2017-09-29---

---2017-07-25--- https://github.com/wangjiegulu/kotlin-for-android-developers-zh/blob/master/shu_xing.md 关于Kotlin的属性访问问题,如果想要最终的控制,可以这么操作

public classs Person {
    var name: String = ""
        get() = field.toUpperCase()
        set(value){
            field = "Name: $value"
        }
}

注意field是内建的变量,代表当前的属性值. 上面这个东西被叫做backing field.

当操作Java代码的时候,Kotlin将允许使用属性的语法去访问在Java文件中定义的getter/setter方法. 编译器会直接链接到它原始的getter/setter方法.所以当我们直接访问属性的时候不会有性能开销

---2017-07-25---

---2017-06-30--- https://kotlinlang.org/docs/reference/classes.html

The open annotation on a class is the opposite of Java's final: it allows others to inherit from this class. By default, all classes in Kotlin are final, which corresponds to Effective Java, Item 17: Design and document for inheritance or else prohibit it.

open class A {
    open fun f() { print("A") }
    fun a() { print("a") }
}

interface B {
    fun f() { print("B") } // interface members are 'open' by default
    fun b() { print("b") }
}

class C() : A(), B {
    // The compiler requires f() to be overridden:
    override fun f() {
        super<A>.f() // call to A.f()
        super<B>.f() // call to B.f()
    }
}

Companion Objects

In Kotlin, unlike Java or C#, classes do not have static methods. In most cases,it's recommended to simply use package-level functions instead.

那么Kotlin中的package-level functions指的什么?

注意Kotlin里各种final默认情况下,除非显示声明为open.

https://kotlinlang.org/docs/reference/object-declarations.html 大概说了下Kotlin中的像Java里的anonymous class的东西叫 object expression

window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})
open class A(x: Int) {
    public open val y: Int = x
}

interface B {...}

val ab: A = object : A(1), B {
    override val y = 15
}

也可以光声明一个匿名对象

fun foo() {
    val adHoc = object {
        var x: Int = 0
        var y: Int = 0
    }
    print(adHoc.x + adHoc.y)
}

Just like Java's anonymous inner classes, code in object expressions can access variables from the enclosing scope. (Unlike Java, this is not restricted to final variables.) 内部类访问外部类的对象什么的不用final. 那么问题来了 Java中为什么需要final当内部类访问外围类属性什么的时候?

fun countClicks(window: JComponent) {
    var clickCount = 0
    var enterCount = 0

    window.addMouseListener(object : MouseAdapter() {
        override fun mouseClicked(e: MouseEvent) {
            clickCount++
        }

        override fun mouseEntered(e: MouseEvent) {
            enterCount++
        }
    })
    // ...
}

---2017-06-30---

---2017-06-29--- lazy() is a function that takes a lambda and returns an instance of Lazy<T> which can serve as a delegate for implementing a lazy property: the first call to get() executes the lambda passed to lazy() and remembers the result, subsequent calls to get() simply return the remembered result.

val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)
    println(lazyValue)
}

这有在第一次访问str的时候,初始化的代码块才会执行,否则都是直接返回值. 默认状态下lazy的代码块是线程安全的, 如果确定没有多线程访问可以设置LazyThreadSafetyMode.NONE

val str: String by lazy(LazyThreadSafetyMode.NONE) {
    println("Executed")
    "Hello Kotlin"
}

Observable Delegates.observable() takes two arguments: the initial value and a handler for modifications. The handler gets called every time we assign to the property (after the assignment has been performed). It has three parameters: a property being assigned to, the old value and the new one:

// sample demo
import kotlin.properties.Delegates

class User {
    var name: String by Delegates.observable("initial_value") {
        _, old, new ->
        println("$old -> $new")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "first"
    user.name = "second"
}

and the output is: initial_value -> first first -> second

http://www.preslav.me/2016/06/26/kotlin-basics-apply-and-copy/

apply() Here is a sample about how to use apply()

private A updateA(A objA, B objB) {  
    objA.setC(objB.getC());
    objA.setD(objB.getD());
    return objA;
}

Note the return value is A. and in Kotlin you can simplify above code like: fun updateA(objA: A, objB: B): A = objA.apply { c = objB.c; d = objB.d }

copy() Please, remember that using apply on an object is NOT a thread-safe operation, and mutates the state of the object. If you want to retain the original object and return an immutable copy of it, you can use the function copy(), provided in all instances of data classes.

what is Data classes https://kotlinlang.org/docs/reference/data-classes.html

data class User(val name: String, val age: Int)  

and Here is a piece of code

val user1 = User("John Smith", 24)  
val user2 = user1.copy(age = 31) 

---2017-06-29---

---2017-06-28--- AndroidStudio配置Kotlin开发环境 1.安装Kotlin插件 Version: 1.1.3-release-Studio2.3-1 2.Configure Kotlin in Project Kotlin compiler and runtime version 1.1.3 3.让sourceset包含kotlin 在build.gradle文件中加入如下配置 sourceSets { main.java.srcDirs += 'src/main/kotlin' }

In Kotlin there is no static keyword to create a static member for a class but exists something called companion objects which allows you to provide the same behavior.

data class RedditNews(...)
    companion object {
        val ENDPOINT = "http://kotlinlang.org"
    }
}

and use it like

RedditNews.ENDPOINT

---2017-06-28---

---2017-06-25--- 关于Null安全 https://kotlinlang.org/docs/reference/null-safety.html

Kotlin中的引用类型默认情况下不能被赋值为null. 除非显示声明 如: var str : String? = null 在Type?表示允许Type类型的引用被赋值为null. 于是又引入了一个?.和!!操作符号 var len = str?.length 这个语句其实就是一个if判断null的简化版. 也就是说如果str是null的话,不会有NPE. 只是 len的值为null而已

str!!.length
这个强制调用str的方法而不管str是否为null. 这样如果str为null就会有NPE抛出

or perform a certain operation only for non-null values, you can use the safe call operator together with let: let操作符. val listWithNulls: List<String?> = listOf("A", null) for (item in listWithNulls) { item?.let { println(it) } // prints A and ignores null }

然后是Elvis Operator(?:) When we have a nullable reference r,we can say "if r is not null, use it, otherwise use some non-null value x": 如: val x:Int = if (b != null) b.length else -1

Elvis操作符牛逼的地方是不仅可以赋额外的值,还是有return或者throw语句. 这在function中将变得很有用,如: fun foo(node: Node): String? { val parent = node.getParent() ?: return null val name = node.getName() ?: throw IllegalArgumentException("name expected") // ... }

Safe Casts ?as 操作 val aInt: Int? = a as? Int 如果a是int的那么没问题,如果不是那么aInt的值就是null. 这在传统Java中将会抛出ClassCastException.

---2017-06-25---

The words “extends” and “implement” were replaced by a colon “:” public class MainActivity extends AppCompatActivity 变成了 class MainActivity : AppCompatActivity()

Functions public void onCreate(Bundle saveInstanceState) 变成了 override fun onCreate(saveInstanceState: Bundle?) :Unit

注意kotlin中参数列表和Java中的方式相反 Java的Void类型对应kotlin的Unit 在Kotlin中一个函数的返回值在()右边通过冒号声明 如 :String 这和Python很像啊 而且kotlin中函数的最后一行语句自动当作返回值,也就是说你可以没有retrun xxx. 如果没有返回值,你甚至可以在声明处省略:Unit

Kotlin中不用;

Values and Variable The way to define a variable is with the “var” keyword. The type will be inferred from the Context and the same for constants which use the “val” keyword:

Nullable 除非你通过语法指定可以为null否则默认情况下变量不能为null 语法就是在类型后面添加一个问号,如: val context : Context? = null val res = context?.getResources() // not crash, res will be null

val context : Context? = null val res = context?.getResources() val appName = res?.getString(R.string.app_name) val shortName = appName?.substring(0, 2)

有一个叫smart cast的特性可以用来解决到处用?引用变量的问题 val context : Context? = null context?.let { val res = context.getResources() // Don't need '?' anymore val appName = res.getString(R.string.app_name) val shortName = appName.substring(0, 2) }

Elvis Operator ?: you can use it to give an alternative value in case the object is null try { // code... } catch (e: Throwable) { Log.e("TAG", e.message ?: "Error message") }

Statically Typed 不明白这说的是个什么东西? 但是有一个例子 we don’t have to specify the type when we create a variable (or a constant in this case). Checkout the toolbar constant, the type is inferred from the context and this is another great feature about Kotlin: val toolbar = findViewById(R.id.toolbar) as Toolbar 说了不用specify the type,但是后面的as Toolbar不和声明类型一样吗?

init关键字 这个有点儿像Java的constructor.usage: 通常这个init的代码块都是在某个类里的 class MyName { init { //to sth } }

Object Expressions In Kotlin you have something called “Object expressions”, which works in a similar way as anonymous inner classes in Java, and allows you to create an object without explicitly declaring a new subclass for it.

private val loadingItem = object : ViewType { override fun getViewType() : Int { return AdapterConstants.LOADING } }

Single Expressions The getViewType() method has only a single expression function inside the body. In Kotlin we can take advantage of this and convert it like this.

override fun getViewType() : Int { return AdapterConstants.LOADING }

Also you don’t have to specify the return value type as it can be inferred by the context. So this is how it looks now: private val loadingItem = object : ViewType { override fun getViewType() = AdapterConstants.LOADING }

Kotlin当中创建对象都不带有new的. in Java: new Person() in Kotlin: Person()

Data class 得先看如果是Java来实现的例子

public class RedditNewsItem {

private String author;
private String title;

public MyNews(String author, String title) {
    this.author = author;
    this.title = title;
}

public String getAuthor() {
    return author;
}

public void setAuthor(String author) {
    this.author = author;
}

public String getTitle() {
    return title;
}

public void setTitle(String title) {
    this.title = title;
}

}

in Kotlin

data class RedditNewsItem(var author: String, var title: String)

通过这样一行代码,每个Properties自动有getter和setter. 并且还有一个构造方法接受的参数就是这两个properties.

转载于:https://my.oschina.net/tanghaoo/blog/1862018

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值