Moved to https://developer.android.com/kotlin/!
android / kotlin-guides Goto Github PK
View Code? Open in Web Editor NEWA set of guides for writing Kotlin for Android.
Home Page: https://android.github.io/kotlin-guides/
A set of guides for writing Kotlin for Android.
Home Page: https://android.github.io/kotlin-guides/
Moved to https://developer.android.com/kotlin/!
I'm translating guides to Chinese, but wondering how to contribute without modifying the source file.
Any help would be appreciated.
The function names section permits using underscores in test function names to ease reading: @Test fun pop_emptyStack()
I propose:
@Test fun `pop emptyStack`()
They combine whitespace, wrapping, documentation, and annotations together.
The style guide doesn't talk about naming enum constants. They don't fall under "Constant values can only be defined inside of an object or as a top-level declaration", so they are not covered by that rule, and there should be a separate one for them.
(And please don't require UPPER_CASE for all enum constants; that would be ugly. Our style guide allows both UPPER_CASE and CamelCase.)
When using the Kotlin Android Extensions plugin (https://kotlinlang.org/docs/tutorials/android-plugin.html) which automatically provides properties for your views, so you do not have to do lookup via findViewById, the naming convention for these IDs are in many cases in conflict with variable and property naming conventions. Should ID's follow camelCase patterns, or should property names deviate from the convention in this situation?
I think the style guide would benefit from saying something about this, but there is probably a discussion that needs to be had before we can define any style guide for this - hence this post.
My personal view is that any ID naming conventions should yield to Kotlin naming conventions in this case, as the impact of changing the naming convention will have a bigger positive impact on code readability than the negative impact on layout file readability.
Commence discussion! :)
https://android.github.io/kotlin-guides/interop.html#function-overloads-for-defaults
mentions this but in a different context.
This is useful even in pure Kotlin, regardless of Java interop because it doesn't require naming the other parameters at the call site.
data class Pizza(val cheese: Boolean, val toppings: List<String> = listOf())
Pizza(true)
instead of
data class Pizza(val toppings: List<String> = listOf(), val cheese: Boolean)
Pizza(cheese = true)
Whitespace -> Horizontal -> 5. declaration
https://android.github.io/kotlin-guides/style.html#import-statements
Wildcard imports (of any type) are not allowed.
This rule seems contradictory to currently accepted standards for general Kotlin and Kotlin w/ Android development. To borrow from what @Rosomack and others said in this ktlint issue about wildcard imports:
Kotlin coding conventions never mention rules for imports. Also, it reasons to stand that usage of wildcard imports should be by coder-preference given that the language allows them. Why should the Android Kotlin style guide have rules about imports when Kotlin does not?
According to @BenjaminSchaaf, the source code for Kotlin itself contains over 6000 wildcard imports across 35303 Kotlin source files.
ItelliJ / Android Studio use wildcard imports by default in these cases:
java.util.*
(ex. LinkedList)import kotlinx.android.synthetic.main.activity_main.*
Note that this is specific behavior set up by the plugin, not because of > 5 names being used.
Most Kotlin linters (such as ktlint) are based off this style guide. Because of this rule, programmers are having to go out of their way to change the default behavior of the IDE to stop using wildcard imports altogether. I propose this rule be removed from the guide.
Properties and functions may often have more keywords which order is not strictly ordered in Kotlin but may be confusing. Few examples:
lateinit
on properties:
private lateinit var foo: Foo
- OKlateinit private var foo: Foo
- WRONG, breaks the relation between lateinit
and var
, the visibility modifier is kind of optinal (when public
)abstract
on functions:
protected abstract fun foo()
- OKabstract protected fun foo()
- WRONGopen
/final
on properties and functions:
open protected val foo: Foo
- seems better to meprotected open val foo: Foo
final override fun foo()
- seems better to meoverride final fun foo()
Do you think such rules might be valuable in the Style Guide?
The style guide says that expression functions should not wrap to two lines. But the IDE inspection suggests that even multi-line functions with a single expression should be converted to an expression function:
I feel very dumb asking this, which is supposedly simple, but I searched all over the documentation and couldn't find anything.
There are a few operations that take a lot of space. For instance, a Firebase call might be:
FirebaseFirestore
.getInstance()
.collection("meetings")
.document(currentId)
.collection("all")
...
.whereEqualTo("kind", kind)
.get()
.addOnCompleteListener { ... }
Is there supposed to be any rule regarding this kind of thing? For example, always break the line when there are more than two operations/"." going on..
I'm not sure if it is non-existent because "common sense" is enough, someone forgot, or it is there, but I couldn't see.
Thanks!
Perhaps as a plugin so that it's constantly updating?
I was wondering if there were currently any thoughts on constructors and guidelines around those, or if these are more of a personal preference / per basis thing?
For example, using the primary constructor where only a few param passed in is usually quite readable, but there may be some cases where there are multiple classes passed in which can cause things to get a little hard to read within a primary constructor. The constructors here are probably a bit of an exageration but are just for example case.
class ExampleClass @Inject constructor(private val dogRepository: DogRepository,
private val catRepository: CatRepository, private val fishRepository: FishRepository,
private val rabbitRepository: BirdRepository, private val birdRepository: BirdRepository)
: SomeClass { }
compared to:
class ExampleClass : SomeClass {
private val dogRepository: DogRepository
private val dogRepository: DogRepository
private val catRepository: CatRepository
private val fishRepository: FishRepository
private val rabbitRepository: BirdRepository
private val birdRepository: BirdRepository
@Inject constructor(dogRepository: DogRepository, catRepository: CatRepository,
fishRepository: FishRepository, rabbitRepository: BirdRepository, birdRepository) :
BirdRepository) {
//assign fields
}
}
For data classes and objects this is usually a lot more readable, but for other classes it can become harder to read.
This could be down to a lower level problem of class design and structure, but it would be good to hear if anyone is already enforcing some form of rule as I guess I'm looking for some kind of consistency ๐ Maybe you're enforcing secondary constructors for certain classes or limiting constructors to a certain number of parameters - or you're not doing anything and just going with your gut!
The style guide says that spaces are required "On both sides of any binary operator.", and does not give an exception for the .. operator. However, various examples do show that you prefer .. to be used without spaces around it. The exception should be noted explicitly.
One line for expression functions?!? I must rebel on this one.
I like seeing code like this:
fun computeCollatzSteps(n: Int) = generateSequence(n) {
require(it > 0)
if (it % 2 == 0) it / 2 else it * 3 + 1
}.takeWhile({ it != 1 }).count()
Versus something like this:
fun computeCollatzSteps(n: Int): Int {
require(n > 0)
return generateSequence(n) {
if (it % 2 == 0) it / 2 else it * 3 + 1
}.takeWhile({ it != 1 }).count()
}
This function is for counting the number of steps in the Collatz Conjecture for a number. Taken from here http://exercism.io/exercises/kotlin/collatz-conjecture/readme
I know the second one is better because it calls require only once. But I added that so I could call out the reason for my argument, which is not for efficiency but for a certain coding style. When efficiency is not a concern but rather the benefits of functional programming are important, I feel that function expressions lead themselves towards this.
I do not claim to be an expert on functional programming by any means. I am a total newbie to these concepts. Concepts that have been around for a long time. But when you lock down a function in Kotlin into a simple expression format, to me it adds constraints on that function that make it work in more of a purely mathematical way. It makes it harder for the coder to write a none pure function. While it is still possible, I feel like it limits your options with the function, and encourages you to keep it more focused on its task.
I like having those limitations, I like having to think in a functional chain. Why? I feel like it makes code less error-prone. Also, forget being "cute", I think code written in this manner can actually be easier to read and maintain. Having one stream of flow to a function forces you to not rely on state manipulating changes. While that is still possible, I would frown on that in an expression function and strive for a purely functional approach. An approach where we have the same output for every input used.
Obviously a matter of opinion, but I think we should open expression functions to being more than one line for those of us that use them to express our code in that manner. My ask is for this restriction in the coding style to be removed, and for functional programming styles to be encouraged.
Perhaps the rule should be if your expression function does not modify the state of its surrounding code container and it always returns the same output for every input then multiple lines should be allowed.
One line is not enough to express some mathematical functions.
Also, nevermind simple cases where we have long class names ;) For example:
Ie.
@Provides fun provideDatabase(context: Context): AppDB =
Room.databaseBuilder(context, AppDB::class.java, dbName).build()
That's 123 characters on one line.
I don't want to have to write that as a function with the return
keyword.
Personally, I'd like to see the return keyword taken out back and put on a shelf for only the most necessary of use cases.
In my mind, you either have a void method that is doing a bunch of setup work or you have a function that returns some result. That result returned should be simple enough that an expression function should suffice.
Those that are more informed on these topics than I, please call me out where I am wrong on any concepts that I am thinking/writing here!
This one line rule for expression functions does not sit right with me.
So in conjecture with possible varying opinions on the matter of expression functions, would it be possible to loosen up this restriction?
We could perhaps say, "Multiple lines are allowed for expression functions that are pure functions"
A pure function is a function where the return value is only determined by its input values, without observable side effects.
My two cents, and this is by no means critical. Just sharing my opinion at the moment =)
Blocked by:
Still broken on parameterized functions, but there's no issue tracking that. This is fixed in Rogue 3 which is in Jekyll master but not released. Once done GitHub Pages will need to update to use that version of Jekyll and that version of Rogue.
Suggestion if you do not change anything else think about the beginner with Kotlin and Android Studio
The path to Lint Checks in kotlin-guides page reads as follows
File -> Preferences -> Editor -> Inspections
I am sure Preferences does not equal the word Settings also sure Preferences was used at one time
this compounded by the accompanying screen shot is nothing but confusing to beginners lets change it
As a Android novices I have learned to read between the lines a skill no one should need to develop
Screen shot included no I did not edit as a novices my skill level is not proficient enough
Any chance of a table of contents in the Style Guide and the Interop Guide, like the one at the top of the Google Java Style Guide?
Thanks - these documents are incredibly useful to have!
Can this be done as a configuration for one of the existing ones?
The style guide is currently silent about which of these is preferred:
someFunction(
someOtherFunction(
someThirdFunction(
param1,
param2,
param3)))
someFunction(
someOtherFunction(
someThirdFunction(
param1,
param2,
param3
)
)
)
The Google Java style guide mandates the first style and it'd be great if the Kotlin style guide was similarly specific. Doesn't matter to me which of the two styles it settles on, just that it picks one for consistency.
Is the recommendation for companion objects? Should they be at the bottom or top of a class?
The guide sets the following guidelines for single-expression functions:
Expression functions should not wrap to two lines. If an expression function grows to require wrapping, use a normal function body, a
return
declaration, and normal expression wrapping rules instead.
It should be understood that it prohibits the use of this kind of constructs:
fun veryVeryLongFun() =
callsAVeryVeryLongFunctionWithHorribleName(andTonsAndTonsOfParameters)
Instead, the following form should be used:
fun veryVeryLongFun() {
return callsAVeryVeryLongFunctionWithHorribleName(andTonsAndTonsOfParameters)
}
However, the following expression function, although multiline, doesn't contain wrapping, as it returns a single multiline expression:
fun getFoo(index: Int) = when (index) {
in 0..10 -> "foo"
in 11..20 -> "bar"
else -> "baz"
}
It's easy to misread the style guide and get the impression that expression functions are only valid if they occupy exactly one line. It would be great to have a more clear description of the wrapping rules in this case.
The Kotlin language code style documentation makes clear that for multi-line, multi-argument method calls the arguments should appear on their own lines (potentially in groups):
drawSquare(
x = 10, y = 10,
width = 100, height = 100,
fill = true
)
where (
ends the line it is on while the )
appears on its own line. The specific rule is
In long argument lists, put a line break after the opening parenthesis. Indent arguments by 4 spaces. Group multiple closely related arguments on the same line.
Is there any guidance for long method calls that wrap to multiple lines when there is only a single argument?
For example, are both the following correct?
setOnClickListener(object : View.OnClickListener {
override fun onClick(v: View) {
//...
}
})
setOnClickListener(
object : View.OnClickListener {
override fun onClick(v: View) {
//..
}
}
)
or is one preferred (ignoring for now that you'd just use a lambda here)? What if there is wrapping involved in the argument value itself? Are each of these valid:
someMethod(callsAVeryVeryLongFunctionWithHorribleName(
andTonsAndTonsOfParameters,
andMoreParameters
))
someMethod(
callsAVeryVeryLongFunctionWithHorribleName(
andTonsAndTonsOfParameters,
andMoreParameters
)
)
The current Google style guide requires 8-space indent for wrapped function parameter lists: https://android.github.io/kotlin-guides/style.html#functions
In our style guide, we'd really prefer to require 4-space indents. The reason why 4-space indents work better is primary constructor parameters: we really want to have the same indent for val/var properties defined in the primary constructor and in the body of the class. And to separate the parameters from the body, the wrapped closing parenthesis followed by the opening curly brace (which your current example already shows) works well enough.
Is there any strong reason why you prefer 8-space indents? If not, could you change the guidance?
I think Java prefers
if (condition1
&& condition 2
|| condition3) {
// do something
}
This style would make sense to me in Kotlin as well, but I couldn't find anything regarding to that in the IJ Kotlin style guide or Android style guide. Note that there has been some discussion going on in the ktlint project what prefers
if (condition1 &&
condition2 ||
condition3) {
// do something
}
An if/else conditional that is used as an expression may omit braces only if the entire expression fits on one line.
https://android.github.io/kotlin-guides/style.html#expressions
I propose to relax the rule to allow
val value = if (string.isEmpty())
calculator.zero() else
calculator.one()
It's a syntax that I first saw in kotlinx.coroutines
and after getting used to it, I found it to be elegant
// https://github.com/Kotlin/kotlinx.coroutines/blob/985f56e54060d05387d25319e630f39e2cce5d5d/js/kotlinx-coroutines-core-js/src/main/kotlin/kotlinx/coroutines/experimental/Deferred.kt#L143-L155
public actual fun <T> async(...): Deferred<T> {
val newContext = newCoroutineContext(context, parent)
val coroutine = if (start.isLazy)
LazyDeferredCoroutine(newContext, block) else
DeferredCoroutine<T>(newContext, active = true)
coroutine.initParentJob(newContext[Job])
start(block, coroutine, coroutine)
return coroutine
}
The current guide says: "When a line is broken at a non-assignment operator the break comes before the symbol". Unfortunately this breaks semantics for +/- operators, which can be used in unary form. For example, this is a string concatenation:
val s = "abc" +
"def"
This is a simple string initialization, followed by an unused expression that applies unary + to a string literal:
val s = "abc"
+ "def"
The wrapping rules should be changed to either break after all operators (preferably), or to make exceptions for +/-.
What's the reasoning behind having a 100 character limit? I advocate bumping it to 120.
let
/run
/etc functions add a lot of indentingNote: The primary goal for line wrapping is to have clear code, not necessarily code that fits in the smallest number of lines.
I believe 120 helps achieve this goal by not forcing line breaks when they don't make sense. Though of course this could be abused.
Many developers have adopted the mHungarian
notation (prefixing fields with a 'm') in their Android apps based off of early Android samples and the Android source code itself. Even though it has since come to light that field prefixing is not recommended, I've seen this style creeping into Kotlin now too unfortunately.
Could the Android Kotlin Style guide be updated to explicitly state that hungarian notation should not be used?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.