介绍
免责声明: 此参考最初已被公布为a Dzone Refcard..
kotlin. 已成为过去几个月最受欢迎的JVM语言之一。在谷歌制作彩票3d字谜为Android开发的官方语言之后,它在Android社区中经历了很多关注。 彩票3d字谜正在开发 码头 ,谁负责最着名的ides,最值得注意的是 intellij想法。尽管如此,它是一个开源语言,可以找到 GitHub. .
据说语言非常 简洁的 , 安全的 就误差频率而言,用Java互操作,还提供了许多功能,使功能编程,写入类型安全的DSL等等。除了JVM旁边,彩票3d字谜可以编译大多数Android版本,使用LLVM向下到机器代码,也可以转发给JavaScript。
彩票3d字谜已经在许多流行的框架和工具中采用,例如春天和地得克。它继续在多个域中获得牵引力,从来没有更好的时间 开始kotlin.
在哪里开始编码
当您想开始编写第一kotlin代码时,有很少的方法可以做到这一点。显然,推荐的方式是使用Intellij Idea合作,这提供了最佳支持。作为替代方案,人们也可以从命令行开始或使用Jetbrains'彩票3d字谜 Web IDE进行一些kotlin koans. 。无论您更喜欢哪种方式,这里可以在此处找到相应的教程:kotlinlang.org/docs/tutorials/。
基本语法
kotlin. was inspired by many modern programming languages like C#, Groovy, Scala and also Java. Even more, 彩票3d字谜 can be seen as an extension to the Java language, making it better by adding functionality to existing standard classes (e.g. String
, List
) and of course by providing great features, which are in large part enabled by applying compiler-supported techniques. As in Java, 彩票3d字谜 programs are entered via a main
method, such as the following:
fun main(args: Array): Unit {
val inserted = " kotlin. "
println("Let's get started with $inserted")
}
我们在此代码段中可以看到的是:
- 功能 are initiated by the keyword
fun
, followed by a name - 参数 并且 变量 在彩票3d字谜通过定义名称和类型来声明,因为您可以在冒号中分隔
args: Array
- 这 return type of the
main
isUnit
, also prefaced by a colon. In case of aUnit
return, which corresponds to Java'svoid
, the compiler does not require you to explicitly define the return type, so the part: Unit
could be omitted - kotlin. 不需要您使用 分号 分离陈述(在大多数情况下)
- 类型推断 is supported in many situations as shown with
val inserted
, which also could be declared with an explicit type asval inserted: String
- 字符串模板 can be used, which means that it's possible to include variables and even expressions in
String
s directly using$varname
or${statement}
syntax main
is declared without a wrapping班级
around it. Functions and variables in 彩票3d字谜 may be declared at "top-level", i.e directly inside a package- 不 可见性修饰 is used here. Functions, classes, variables etc. are
public
经过 default. When different visibility is needed, choose from:
关键词 | 对顶级声明的影响 [1] | 对班级成员的影响 |
---|---|---|
public | 到处都是可见的 | 如果课程可访问,则可见随处可见 |
private | 仅在文件内可见 | 仅在课堂内看到 |
protected | - | 在课堂和子类中可见 |
internal | 在同一模块内可见 [2] | 在同一模块中可见,如果类是可访问的 |
1:可以在“顶级”中声明函数,属性和类,对象和接口
2:模块是一组编译的彩票3d字谜文件:Intellij Idem模块,Maven项目,Pradle源集
- Variables defined as
val
cannot be re-assigned, i.e. are read-only. Alternatively, if mutability is inevitable,var
can be utilized, as shown in the next example:
var mutableVar = StringBuilder("first")
mutableVar = StringBuilder("second")
- Constructor is invoked without the
new
keyword, which is omitted from kotlin
控制流程:条件
In 彩票3d字谜 you can make use of if
, when
, for
and while
for controlling the behavior of your code. Let's look at conditions first.
if-陈述
val min: Int
if (x < y) {
min = x
} else {
min = y
}
很重要,很重要 陈述 在彩票3d字谜也可以用作 表达式 ,例如,在大多数情况下使三元运算符过时并显然缩短了代码:
val min = if (x < y) x else y
When-Statement A when
statement is very similar to switch
operators and could, in theory, easily replace if-statements as they are much more powerful.
val y = when (x) {
0 -> "is zero"
1 -> "is one"
2, 3 -> "two or three"
is Int -> "is Int"
is Double -> "is Double"
in 0..100 -> "between 0 and 100"
else -> "else block"
}
In a when
statement, which can also be used as an expression, all branches are tried to match the input until one condition is satisfied. If no branch matches, the else
is executed. As shown in the snippet, when
branch conditions can be values, types, ranges and more.
控制流程:循环
for-loop.
在彩票3d字谜,没有传统的for-loop,因为您从C或Java知道它。反而, Foreach. 循环是默认值。
for (c in "charSequence") {
println(c)
}
In many cases, looping with an index is necessary, which can easily be achieved with the indices
property that is defined for arrays, lists and also CharSequence
s for example.
for (i in "charSequence".indices) {
println("charSequence"[i])
}
Another way of iterating with indices is possible by using withIndix()
.
for ((i,c) in "charSequence".withIndex()) {
println("$i: $c")
}
最后但并非最不重要的是,彩票3d字谜的范围,也可以用于索引的迭代,如下所示:
(0 .. "charSequence".length-1).forEach {
print("charSequence"[it])
}
这 range in this example is expressed with the common ..
syntax. To create a range which does not include the end element (s.length
), the until
function is used: (0 until s.length)
.
while-loop.
Constructs with while
or do-while
loops are straight-forward, all works as known from other common languages.
基本类型
在彩票3d字谜中,所有内容都看起来像对象,甚至是原始类型。这意味着,可以在每个类型上调用成员函数,但有些则表示为 JVM原语 at runtime.
数字
这 default number types are: Double
, Float
, Long
, Int
, Short
, Byte
*下划线可用于使大量更可读: val million = 1_000_000
* Number types offer conversion methods like toByte(): Byte
, toInt(): Int
, toLong(): Long
*字符在彩票3d字谜中没有数字类型
char
A Char
represents characters and cannot be treated as a number.
*它们在单引号内宣布,例如 '42'
* An explicit conversion from a Char
to an Int
can be accomplished with the toInt()
method
布尔斯
布尔斯
can have the two common values true
and false
* They can be operated on with: ||
, &&
and !
弦
字符串是不可变的字符序列。
* They offer an index operator []
for accessing characters at specified positions
* A string literal in 彩票3d字谜 looks like "Hello World"
or """Hello World with "another String" in it"""
*后者被称为 生的 可以包含任何字符的字符串,而无需逃脱特殊符号
* String
s in 彩票3d字谜 may contain template expressions
阵列
An array is represented by the class Array
, which offers very useful methods to the client.
* Values can be obtained via get(index)
or [index]
* Values can be set via set(index, value)
or [index]=value
* Arrays are invariant, i.e. an Array
cannot be assigned to a variable of type Array
* Special types for arrays of primitive types exist as IntArray
or ShortArray
for instance. Using those will reduce the boxing overhead.
班级
可以在此代码段中声明一个简单的类:
班级 Person constructor(name: String) {}
这 primary constructor is part of the class header, secondary constructors can be added in the class body. In the shown case, the constructor
keyword could also be omitted, since it's only mandatory if you want to add annotations or visibility modifiers (default: public).
Constructor parameters such as name
can be used during the initialization of an object of this class. For this purpose, an init
block would be necessary, because primary constructors can't contain code directly. Constructor arguments can also be used in property initializers that are declared in the class body, as shown here.
班级 Person(name: String, age: Int) {
init {
println("new Person $name will be born.")
}
val ageProp = age
}
As mentioned, 彩票3d字谜 classes can contain properties, which are accessed by simply calling obj.propertyName
to get a property's value and obj.propertyName = "newValue"
to modify the value of 一个可变的 (var
) property. Declaring properties for classes can also be done in the primary constructor directly, which makes the code even more concise. Like in all methods, 彩票3d字谜 supports 默认参数 for parameters, set with "=
".
班级 Person(val name: String, val age: Int = 50)
Same as with local variables, instead of val
, a property can be declared 可变的 using var
instead. Note that you don't have to write an empty class body if no content is defined.
特殊课程
除了普通的课程外,彩票3d字谜还知道一些特殊的类声明,值得了解。以下将提供快速概述。
类型 | 解释 |
---|---|
数据 class | Adds standard functionality for toString , equals , hashCode etc. |
sealed class | 将类层次结构限制为一组子类型。有用 when |
嵌套类 | 可以在其他类中创建类,也称为“内部类” |
enum class | 收集可以包含逻辑的常量 |
object declarations | 用于创建一种类型的单身 |
Of course, 彩票3d字谜 also supports inheritance through interface
s and abstract
classes.
功能类型和lambdas
In order to be able to understand idiomatic 彩票3d字谜 code, it's essential to recognize how function types and especially lambdas look like. Just as you can declare variables of type Int
or String
, it's also possible to declare variables of function types, e.g. (String) -> Boolean
.
val myFunction: (String) -> Boolean = { s -> s.length > 3 }
myFunction("HelloWorld")
这 variable is declared as a function type that takes a String
argument and returns a Boolean
. The method itself is defined as a lambda enclosed in curly braces. In the shown lambda, the String
parameter is declared and named before the ->
symbol, whereas the body follows after it.
lambda特殊语法
语言设计师决定了一些特殊的Lambda功能,这使得使用更强大。
it
:单个参数的隐式名称
In many cases, lambdas are used with single parameters like in the previous example. In such situations, you don't have to give the parameter an explicit name. Instead, the implicit name it
can be used.
val myFunction: (String) -> Boolean = { it.length > 3 }
myFunction("HelloWorld")
- 对于未使用的参数,使用
_
在某些情况下,可能不必在Lambda中使用每种可能的可用参数。编译器警告开发人员关于这种未使用的变量,可以通过命名它来避免 下划线 .
val myFunction: (String, Int) -> Boolean = { s, _ -> s.length > 3 }
myFunction("HelloWorld", 42)
高阶函数
如果函数将另一个函数呈现为参数或返回另一个函数作为其结果,则它被称为a 高阶函数。由于许多库函数依赖于此概念,这些功能在彩票3d字谜中是必不可少的。让我们看一个例子。
fun main(args: Array) {
myHigherOrderFun(2, { it.length > 2 })
}
fun myHigherOrderFun(iterations: Int, test: (String) -> Boolean){
(0 until iterations).forEach {
println("$it: ${test("myTestString")}")
}
}
这 function myHigherOrderFun
defines two parameters, one of which is another function test
. The function takes test
and applies a String
to it multiple times depending on what the first argument iterations
is. By the way, the example uses a 范围 to imitate an indexed for
loop here.
这 shown main
function demonstrates the usage of a 高阶函数 by calling it with an anonymous function. The syntax looks a bit messy, which is why the language designers decided on a very important convention: If a lambda is the 最后的 对函数的参数,可以放置 后 关闭括号或者,如果是的话 只要 argument, the parentheses can be omitted completely like shown with forEach
above. The following snippet demonstrates this convention applied to an invocation of myHigherOrderFun
.
//Lambda after closing parentheses
myHigherOrderFun(2) {
it.length>2
}
顶级特色
kotlin. 有一些功能,每个人都应该熟悉。这些对于许多图书馆,标准函数以及高级功能至关重要 域特定语言 support.
零安全
这 type system differentiates between nullable and non-null types. By default, a class like String
cannot reference null
, which raises the attention for null
-related problems. As opposed to String
, the type String?
can hold null
. This does not make a big difference on its own. Therefore, working with nullable types implies having to handle nullable values in a special way.
var b: String? = "couldBeNull"
b = null //okay
// 1. Access directly: does not compile, could throw NPE
// val len = b.length
//2. Use safe-operator
val len = b?.length
//3. Check nullability before accessing
if(b != null){
b.length
}
It's possible to check whether a variable is not null
before accessing it. In such cases, the compiler permits the usage without special safety measures. Alternatively, b?.length
expresses: call length
on b
if it's not null
, otherwise the expression returns null
. The return is of type Int?
because null
may be returned. Chaining such calls is possible, which is very useful. Other operators used with nullable types are shown in the following overview.
操作员 | 用例 | 例子 |
---|---|---|
! | 忽略编译器的警告并克服null检查。仅限谨慎使用。 | x!!.length |
?: | 这 埃尔维斯运营商 is used to give an alternative for null results. | val len: Int = b?.length ?: 0 |
作为? | A 安全铸造 tries to cast a variable in a type and results in null if the cast is not possible. | val i: Int? = s as? Int |
延期
kotlin. 的另一个基本特征是 延期 . An extension is used to extend a class with new functionality without having to inherit from that class. Extensions can have the form of properties and functions. The 彩票3d字谜 standard library contains a lot of such extensions, like the following defined on String
:
public fun String.substring(range: IntRange): String =
substring(range.start, range.endInclusive + 1)
//usage
"myString".substring(0..3)
In this example String
is the 接收者 of the defined substring(range: IntRange)
function. An extension function can use visible members of its receiver without additional qualifiers since this
refers to the receiver. In the snippet, String
's standard method substring(startIndex: Int, endIndex: Int)
is called in that way. The extension is called on a String
as if it was a regular method.
也可以扩展课程 特性 . For example, Int
can be extended with a property that represents its version of BigDecimal
. This might be useful if otherwise, the constructor of BigDecimal
had to be used many times.
val Int.bd
get() = BigDecimal(this)
val bd: BigDecimal = 5.bd
扩展主要在顶级定义,可以在显式导入之后在其他文件中使用。
Lambda与接收器
如果与“带接收器的Lambdas”一起使用,高阶函数可能更强大。可以使用特定的接收器对象调用函数文字,类似于扩展功能。结果,接收器的成员可以直接在Lambda内部访问,而无需使用额外的限定符。这个功能是彩票3d字谜对写作的奇妙支持的基础 类型安全的建筑商,也被称为 域特定语言.
fun T.apply(block: T.() -> Unit): T {
block()
return this
}
This snippet shows a slightly simplified version of the apply
function, which is part of 彩票3d字谜's standard library. It's an extension function on the generic type T
, thus can be used with any object. The function takes a function literal with T
as its receiver and executes the block before this
(the receiver of apply
) is being returned.
数据 class GuiContainer(
var width: Int = 0,
var height: Int = 0,
var background: String = "red"
) {
fun printMe() = println(this)
}
fun main(args: Array) {
val container = GuiContainer().apply {
width = 10
height = 20
background = "blueish"
printMe()
}
}
In this example, the data class GuiContainer
is created with default parameters and then the apply
method is called on it. It's possible to set mutable properties and call methods of the receiver GuiContainer
like shown with the invocation of printMe()
in the end. Since apply
returns the receiver after it completes, it can directly be assigned to a variable.
惯用kotlin.
kotlin. 试图鼓励特别的 编码成语 要使用的。这些部分是部分的 上市 在文档中也在一些社区驱动的文章中。以下将以示例呈现一些这些成语。
- 采用
when
as an expression if possible
fun analyzeType(obj: Any) =
when(obj){
is String -> "is String"
else -> "no String"
}
- 采用 埃尔维斯 operator with
throw
andreturn
to handle nullable values
班级 Person(val name: String?, val age: Int?)
fun process(person: Person) {
val pName = person.name ?: throw IllegalArgumentException("Name must be provided.")
println("processing $pName")
val pAge = person.age ?: return
println("$pName is $pAge years old")
}
- 利用 范围 checks
fun inLatinAlphabet(char: Char) = char in 'A'..'Z'
- 更喜欢 默认参数 功能超载
fun greet(person: Person, printAge: Boolean = false) {
println("Hello ${person.name}")
if (printAge)
println("${person.name} is ${person.age} years old")
}
- 采用 别名 for function types
typealias StringPredicate = (String) -> Boolean
val pred: StringPredicate = {it.length > 3}
- 采用 数据 多个返回值的类
数据 class Multi(val s: String, val i: Int)
fun foo() = Multi("one", 1)
fun main(args: Array){
val (name, num) = foo()
}
- 更喜欢 扩大 函数到实用型功能
fun Person.greet(printAge: Boolean = false) {
println("Hello $name")
if (printAge)
println("$name is $age years old")
}
- 采用
apply
for object initialization
数据 class GuiContainer(
var width: Int = 0,
var height: Int = 0,
var background: String = "red"
) {
fun printMe() = println(this)
}
fun main(args: Array) {
val container = GuiContainer().apply {
width = 10
height = 20
background = "blueish"
printMe()
}
}
- 采用
compareBy
for complex comparisons
fun sort(persons: List): List =
persons.sortedWith(compareBy(Person::name, Person::age))
- 采用
mapNotNull
to combinemap
andfilter
for non-null values
fun getPersonNames(persons: List): List =
persons.mapNotNull { it.name }
- 采用
object
to apply Singleton pattern
object PersonRepository{
fun save(p: Person){}
//...
}
//usage
val p = Person("Paul", 40)
PersonRepository.save(p)
- 不要使用
!
//Do not use !!, there's always a better solution
person!!.address!!.street!!.length
- 更喜欢只读数据结构
//Whenever possible, do not use mutable Data Structures
val mutableList: MutableList = mutableListOf(1, 2, 3)
mutableList[0] = 0
val readOnly: List = listOf(1, 2, 3)
readOnly[0] = 0 // Does not compile
- 采用
let
to execute code if receiver is 没有空
fun letPerson(p: Person?) {
p?.let {
println("Person is not null")
}
}
资源
语言参考:
官方参考文件: //kotlinlang.org/docs/reference/
github存储库: //github.com/JetBrains/kotlin
工具和框架的集合: //kotlin.link
运营商和关键字概述: //kotlinlang.org/docs/reference/keyword-reference.html
社区:
松弛: //kotlinlang.slack.com
推特: //twitter.com/kotlin
通讯: http://kotlinweekly.net
讨论: //discuss.kotlinlang.org
博客:
码头: //blog.jetbrains.com/kotlin/
Simon Wirtz: //kotlinexpertise.com
MISC:
彩票3d字谜在行动书中: kotlin在行动中
图书: //kotlinlang.org/docs/books.html
在线IDE: //try.kotlinlang.org
Simon是一名软件工程师,拥有9年以上的经验开发在多个平台上的软件,包括JVM和无服务环境。他目前为决策自动化SaaS平台构建可扩展的分布式服务。西蒙是一个自我任命的kotlin爱好者。
[…]读它们。自从我开始学习彩票3d字谜编程语言以来,我喜欢帮助别人解决他们的彩票3d字谜相关问题。这是我创建帐户并贡献的初始动力和贡献[…]
[…]读它们。自从我开始学习彩票3d字谜编程语言以来,我喜欢帮助别人解决他们的彩票3d字谜相关问题。这是我创建帐户并贡献的初始动力和贡献[…]
[…]有关彩票3d字谜功能的更详细介绍,您可以看看我的入门指南。 […]
[…]文章涵盖了彩票3d字谜的泛型和差异的概念,并将其与Java进行了比较。 彩票3d字谜泛型与Java不同’s在他们的差异如何是[…]
[…]可以阅读更多关于彩票3d字谜的信息’这个令人敬畏的功能[…]