Reputation: 43
Edited: What and how it work? This is a kotlin dsl language.
fun ClassName.funcName(): (Type ) -> Type = {func body}
um this is one of the implementation I found, and also see the concrete syntax to this link: https://dzone.com/articles/the-complete-custom-gradle-plugin-building-tutoria
private fun CodeLinesExtension.buildFileFilter():
(File) ->
Boolean =
if (fileExtensions.isEmpty()) {
{ true }
} else {
{ fileExtensions.contains(it.extension) } // filter by extension
}
if you CALL this one as a arguments in ".filter(...)", what would happed in the "(File)" syntax, is it automatically receive an arguments?
someFiles.filter(CodeLinesExtension.buildFileFilter()).forEach{...}
Upvotes: 0
Views: 449
Reputation: 37650
There are many things at play here.
fun SomeClass.funcName()
is the syntax for declaring extension functions. These are used just like regular methods of the class SomeClass
, but can be defined outside of the class, and it's especially useful on classes that you don't control.
The return type of the function you mention is (File) -> Boolean
. This expression describes a function type. In this specific case, it is the type of all functions that take a File
as single argument, and return a Boolean
.
This means that your buildFileFilter()
function is an extension function that itself returns a function (File) -> Boolean
.
As you can see in the function's body, inside the if
statement, there are braces to define the blocks of the if
-else
({ ... }
), but also braces inside those blocks. This is because Kotlin uses braces for lambda expressions (literals for anonymous functions).
{ true }
is a lambda expression that represents a function that may or may not take arguments, but returns true
every time.
So this code:
if (fileExtensions.isEmpty()) {
{ true }
} else {
{ fileExtensions.contains(it.extension) } // filter by extension
}
returns either:
{ true }
- a function that takes a File
as argument and always returns true, or{ fileExtensions.contains(it.extension) }
- a function that takes a File
as argument and returns whether fileExtensions
contains the extension of the File
that it receives (it
is the implicit name for the File
argument)Note: the fact that these functions take a File
as argument is inferred by the compiler based on the return type of buildFileFilter()
.
if you CALL this one as a arguments in ".filter(...)", what would happed in the "(File)" syntax, is it automatically receive an arguments?
filter()
itself actually expects a function as argument. The function you pass to filter()
is called a predicate, because it takes one element of the list as argument and returns a Boolean
that says whether this element should be included in the resulting list.
So if you apply filter
to a List<File>
, the predicate expected by filter
is exactly of type (File) -> Boolean
(it says whether we should put this File
item in the resulting collection).
Calling buildFileFilter()
returns a function as we have seen, and the function is perfectly of the right type to use it in filter
. The File
argument of the function returned by buildFileFilter()
will be given by the filter
function itself when it calls your filter function.
Upvotes: 2