协同程序实际上是一种轻质线程(light-weight thread),可以在以后暂停和恢复(suspended and resumed later)。 通过挂起函数(suspending functions)支持协同程序:调用这样一个函数可能会暂停协同程序,而要启动一个新的协同程序,我们通常使用一个匿名挂起函数(anonymous suspending functions)(即suspending lambdas)。
我们来看看async/await ,这是在外部库kotlinx.coroutines中实现的:
// runs the code in the background thread pool
fun asyncOverlay() = async(CommonPool) {
// start two async operations
val original = asyncLoadImage("original")
val overlay = asyncLoadImage("overlay")
// and then apply overlay to both results
applyOverlay(original.await(), overlay.await())
}
// launches new coroutine in UI context
launch(UI) {
// wait for async overlay to complete
val image = asyncOverlay().await()
// and then show it in UI
showImage(image)
}
import kotlin.coroutines.experimental.*
fun main(args: Array) {
val seq = buildSequence {
for (i in 1..5) {
// yield a square of i
yield(i * i)
}
// yield a range
yieldAll(26..28)
}
// print the sequence
println(seq.toList())
}
typealias OscarWinners = Map
fun countLaLaLand(oscarWinners: OscarWinners) =
oscarWinners.count { it.value.contains("La La Land") }
// Note that the type names (initial and the type alias) are interchangeable:
fun checkLaLaLandIsTheBestMovie(oscarWinners: Map) =
oscarWinners["Best picture"] == "La La Land"
fun oscarWinners(): OscarWinners {
return mapOf(
"Best song" to "City of Stars (La La Land)",
"Best actress" to "Emma Stone (La La Land)",
"Best picture" to "Moonlight" /* ... */)
}
fun main(args: Array) {
val oscarWinners = oscarWinners()
val laLaLandAwards = countLaLaLand(oscarWinners)
println("LaLaLandAwards = $laLaLandAwards (in our small example), but actually it's 6.")
val laLaLandIsTheBestMovie = checkLaLaLandIsTheBestMovie(oscarWinners)
println("LaLaLandIsTheBestMovie = $laLaLandIsTheBestMovie")
}
val numberRegex = "\\d+".toRegex()
val numbers = listOf("abc", "123", "456").filter(numberRegex::matches)
fun main(args: Array) {
println("Result is $numbers")
}
阅读文档(documentation)和KEEP了解更多详情。
密封和数据类 (Sealed and data classes)
Kotlin 1.1删除了Kotlin 1.0中存在的封装和数据类的一些限制。 现在,您可以在同一个文件的顶层定义顶级密封类(sealed class)的子类,而不仅仅是封装类的嵌套类(nested classes of the sealed class)。 数据类(Data classes)现在可以扩展其他类。 这可以用来很好且干净地定义表达式类的层次结构(hierarchy of expression classes):
sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
fun eval(expr: Expr): Double = when (expr) {
is Const -> expr.number
is Sum -> eval(expr.e1) + eval(expr.e2)
NotANumber -> Double.NaN
}
val e = eval(Sum(Const(1.0), Const(2.0)))
fun main(args: Array) {
println("e is $e") // 3.0
}
fun main(args: Array) {
val map = mapOf(1 to "one", 2 to "two")
// before
println(map.mapValues { entry ->
val (key, value) = entry
"$key -> $value!"
})
// now
println(map.mapValues { (key, value) -> "$key -> $value!" })
}
阅读文档(documentation)和KEEP了解更多详情。
用于未使用参数的下划线 (Underscores for unused parameters)
对于具有多个参数的lambda,可以使用_字符替换不使用的参数的名称:
fun main(args: Array) {
val map = mapOf(1 to "one", 2 to "two")
map.forEach { _, value -> println("$value!") }
}
这也在解构声明中起作用:
data class Result(val value: Any, val status: String)
fun getResult() = Result(42, "ok").also { println("getResult() returns $it") }
fun main(args: Array) {
val (_, status) = getResult()
println("status is '$status'")
}
阅读KEEP了解更多详情。
用于数字文字的下划线 (Underscores in numeric literals)
就像Java 8一样,Kotlin现在允许在数字文字中使用下划线来分隔数字组:
val oneMillion = 1_000_000
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
fun main(args: Array) {
println(oneMillion)
println(hexBytes.toString(16))
println(bytes.toString(2))
}
阅读KEEP了解更多详情。
更短的属性语法 (Shorter syntax for properties)
对于将getter定义为表达式主体的属性,现在可以省略属性类型:
data class Person(val name: String, val age: Int) {
val isAdult get() = age >= 20 // Property type inferred to be 'Boolean'
}
fun main(args: Array) {
val akari = Person("Akari", 26)
println("$akari.isAdult = ${akari.isAdult}")
}
public val List.lastIndex: Int
inline get() = this.size - 1
fun main(args: Array) {
val list = listOf('a', 'b')
// the getter will be inlined
println("Last index of $list is ${list.lastIndex}")
}
import java.util.Random
fun needAnswer() = Random().nextBoolean()
fun main(args: Array) {
val answer by lazy {
println("Calculating the answer...")
42
}
if (needAnswer()) { // returns the random value
println("The answer is $answer.") // answer is calculated at this point
}
else {
println("Sometimes no answer is the answer...")
}
}
阅读KEEP了解更多详情。
拦截委托属性绑定 (Interception of delegated property binding)
对于委托属性(delegated properties) ,现在可以使用provideDelegate运算符拦截对属性绑定的委托(intercept delegate to property binding)。 例如,如果我们要在绑定之前检查属性名称,我们可以这样写:
class ResourceLoader(id: ResourceID) {
operator fun provideDelegate(thisRef: MyUI, prop: KProperty<*>): ReadOnlyProperty {
checkProperty(thisRef, prop.name)
... // property creation
}
private fun checkProperty(thisRef: MyUI, name: String) { ... }
}
fun bindResource(id: ResourceID): ResourceLoader { ... }
class MyUI {
val image by bindResource(ResourceID.image_id)
val text by bindResource(ResourceID.text_id)
}
enum class RGB { RED, GREEN, BLUE }
inline fun > printAllValues() {
print(enumValues().joinToString { it.name })
}
fun main(args: Array) {
printAllValues() // prints RED, GREEN, BLUE
}
DSL中隐式接收器的范围控制 (Scope control for implicit receivers in DSLs)
val outDirFile = File(outputDir.path).takeIf { it.exists() } ?: return false
// do something with existing outDirFile
fun main(args: Array) {
val input = "Kotlin"
val keyword = "in"
val index = input.indexOf(keyword).takeIf { it >= 0 } ?: error("keyword not found")
// do something with index of keyword in input string, given that it's found
println("'$keyword' was found in '$input'")
println(input)
println(" ".repeat(index) + "^")
}
val index = input.indexOf(keyword).takeUnless { it < 0 } ?: error("keyword not found")
当您具有可调用引用(callable reference)而不是lambda时也很方便:
private fun testTakeUnless(string: String) {
val result = string.takeUnless(String::isEmpty)
println("string = \"$string\"; result = \"$result\"")
}
fun main(args: Array) {
testTakeUnless("")
testTakeUnless("abc")
}
fun main(args: Array) {
val words = "one two three four five six seven eight nine ten".split(' ')
val frequencies = words.groupingBy { it.first() }.eachCount()
println("Counting first letters: $frequencies.")
// The alternative way that uses 'groupBy' and 'mapValues' creates an intermediate map,
// while 'groupingBy' way counts on the fly.
val groupBy = words.groupBy { it.first() }.mapValues { (_, list) -> list.size }
println("Comparing the result with using 'groupBy': ${groupBy == frequencies}.")
}
Map.toMap() 以及Map.toMutableMap()
这些功能可用于轻松复制映射:
class ImmutablePropertyBag(map: Map) {
private val mapCopy = map.toMap()
}
Map.minus(key)
操作符plus提供了一种方法来添加键值对到只读映射生成一个新的映射,但是没有一个简单的方法来做相反的事情:从映射中删除一个键你必须诉诸不太直接的方法,例如Map.filter()或Map.filterKeys()。 现在操作符minus弥补了这个差距。 有4个重载可用:用于删除单个键(a single key),一合集键(a collection of keys),一系列键(a sequence of keys)和一数组键(an array of keys)。
fun main(args: Array) {
val map = mapOf("key" to 42)
val emptyMap = map - "key"
println("map: $map")
println("emptyMap: $emptyMap")
}
fun main(args: Array) {
val squares = List(10) { index -> index * index }
val mutable = MutableList(10) { 0 }
println("squares: $squares")
println("mutable: $mutable")
}
fun main(args: Array) {
val map = mapOf("key" to 42)
// returns non-nullable Int value 42
val value: Int = map.getValue("key")
val mapWithDefault = map.withDefault { k -> k.length }
// returns 4
val value2 = mapWithDefault.getValue("key2")
// map.getValue("anotherKey") // <- this will throw NoSuchElementException
println("value is $value")
println("value2 is $value2")
}
js数组的操作;
一:数组的创建:
1、数组的创建
var array = new Array(); //创建一个数组
var array = new Array([size]); //创建一个数组并指定长度,注意不是上限,是长度
var arrayObj = new Array([element0[, element1[, ...[, elementN]]]
org.hibernate.TransactionException: JDBC begin failed: at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:68) at org.hibernate.impl.SessionImp
最近要接入微信的收货地址共享接口,总是不成功,折腾了好几天,实在没办法网上搜到的帖子也是骂声一片。我把我碰到并解决问题的过程分享出来,希望能给微信的接口文档起到一个辅助作用,让后面进来的开发者能快速的接入,而不需要像我们一样苦逼的浪费好几天,甚至一周的青春。各种羞辱、谩骂的话就不说了,本人还算文明。
如果你能搜到本贴,说明你已经碰到了各种 ed