Set attributed text to UIButton - uibutton

I am trying to set an attributed string to a button.
The definition of this function on swift is this
func setAttributedTitle(_ title: NSAttributedString!,
forState state: UIControlState)
so I thought I would have to type it like
myButton.setAttributedTitle(title:attrString, forState: UIControlState.Normal)
but the correct is
myButton.setAttributedTitle(attrString, forState: UIControlState.Normal)
why it is necessary to put forState: but not title? I don't get that.
And by the way what is the meaning of that underscore on the func definition?

Because that's how methods parameters work in swift. I emphasize methods, because this doesn't hold true for bare functions, i.e. func definitions outside a class scope.
By default the first parameter is given without an explicit name, which is instead mandatory for the others.
From the official guide
Methods in Swift are very similar to their counterparts in Objective-C. As in Objective-C, the name of a method in Swift typically refers to the method’s first parameter using a preposition such as with, for, or by, as seen in the incrementBy method from the preceding Counter class example. The use of a preposition enables the method to be read as a sentence when it is called. Swift makes this established method naming convention easy to write by using a different default approach for method parameters than it uses for function parameters.
Specifically, Swift gives the first parameter name in a method a local parameter name by default, and gives the second and subsequent parameter names both local and external parameter names by default. This convention matches the typical naming and calling convention you will be familiar with from writing Objective-C methods, and makes for expressive method calls without the need to qualify your parameter names.
The underscore means: this parameter has no external parameter name. For the first arguments of methods this is redundant, but you can use it for instance to change the default behavior discussed above.
For instance
class Foo {
func bar(a: String, b: Int) {}
func baz(a: String, _ b: Int) {}
}
will result in the following proper use of method calls:
var f = Foo()
f.bar("hello", b: 1)
f.baz("hello", 1)
Adding the _ has the effect of making b a local name only, so you cannot do
f.baz("hello", b: 1)

Related

Type inference in Kotlin lambdas fails when using `it` special variable

I fail to understand, why the following compiles:
directory.listFiles { it -> it.name.startsWith("abc") }
but this doesn't:
directory.listFiles { it.name.startsWith("abc") }
Am I correctly assuming that in the first case, the type of it is inferred via the name property? Why is this not happening in the second case?
It is because there are two possible FunctionalInterfaces that can be used with File.listFiles:
listFiles(FileFilter) - this interface is accept(File pathname)
listFiles(FilenameFilter) - this interface is accept​(File dir, String name)
The compiler cannot work out which you want to use. So how is this better in the case you write it ->?
Well, the compiler inspects the call arguments of the two interface methods and can now see you expect one argument "SOMETHING ->," so the only matching call is the FileFilter variation.
How might you use the FilenameFilter? you'd use this syntax:
directory.listFiles { dir, name -> name.startsWith("abc") }
The magic here is not it - that's a coincidence, but that you declared just one parameter.

Kotlin syntax issue

Sorry for the terrible title, but I can't seem to find an allowable way to ask this question, because I don't know how to refer to the code constructs I am looking at.
Looking at this file: https://github.com/Hexworks/caves-of-zircon-tutorial/blob/master/src/main/kotlin/org/hexworks/cavesofzircon/systems/InputReceiver.kt
I don't understand what is going on here:
override fun update(entity: GameEntity<out EntityType>, context: GameContext): Boolean {
val (_, _, uiEvent, player) = context
I can understand some things.
We are overriding the update function, which is defined in the Behavior class, which is a superclass of this class.
The update function accepts two parameters. A GameEntity named entity, and a GameContext called context.
The function returns a Boolean result.
However, I do not understand the next line at all. Just open and close parentheses, two underscores as the first two parameters, and then an assignment to the context argument. What is it we are assigning the value of context to?
Based on IDE behavior, apparently the open-close parentheses are related to the constructor for GameContext. But I would not know that otherwise. I also don't understand what the meaning is of the underscores in the argument list.
And finally, I have read about the declaration-site variance keyword "out", but I don't really understand what it means here. We have GameEntity<out EntityType>. So as I understand it, that means this method produces EntityType, but does not consume it. How is that demonstrated in this code?
val (_, _, uiEvent, player) = context
You are extracting the 3rd and 4th value from the context and ignoring the first two.
Compare https://kotlinlang.org/docs/reference/multi-declarations.html .
About out: i don't see it being used in the code snippet you're showing. You might want to show the full method.
Also, maybe it is there only for the purpose of overriding the method, to match the signature of the function.
To cover the little bit that Incubbus's otherwise-great answer missed:
In the declaration
override fun update(entity: GameEntity<out EntityType>, // …
the out means that you could call the function and pass a GameEntity<SubclassOfEntityType> (or even a SubclassOfGameEntity<SubclassOfEntityType>).
With no out, you'd have to pass a GameEntity<EntityType> (or a SubclassOfGameEntity<EntityType>).
I guess that's inherited from the superclass method that you're overriding.  After all, if the superclass method could be called with a GameEntity<SubclassOfEntityType>, then your override will need to handle that too.  (The Liskov substitution principle in action!)

Extension function on a generic type

I am new in Kotlin and I am trying to understand type alias and functions.
I have the following example:
interface EmptyInterface
typealias GenericCase<T> = T.(EmptyInterface) -> T
val myFunctionVariable: GenericCase<String> = {
_ -> "Hello world!"
}
So far what I understand is that I extend what ever T is defined with a function that accepts as argument an EmptyInterface and returns a T.
So the myFunctionVariable is a function that should be called passing an EmptyInterface
But the following code does not compile
class a: EmptyInterface
println("${myFunctionVariable(a())}")
I need to pass a String as the first parameter:
class a: EmptyInterface
println("${myFunctionVariable("",a())}")
Why is the string needed as the first parameter? T.(EmptyInterface) -> T which in this case is String.(EmptyInterface) -> String has only 1 parameter.
Could someone please explain this?
The T. in the type T.(EmptyInterface) -> T means that this function is an extension function on T. So the regular way to call this function is to acquire a T instance, and call it on that instance, as if it was a member function. In the case of your example, where you chose T to be a String, you have to call the function on a String instance:
"foo".myFunctionVariable(a())
The syntax you've used is an alternative way to call this extension, passing in the receiver as if it was the first parameter of the function (which, at the bytecode level, it actually is):
myFunctionVariable("foo", a())
If you wish to use your function with this syntax, however, it's better to declare it to take two parameters, as this invocation of an extension function can be quite unexpected.
(There's some more info about how you can go back and forth between a function that's an extension on a type and one that takes it as a first parameter in this answer.
In the type T.(EmptyInterface) -> T, the first T is the receiver: an instance that the function is called upon, and which becomes this within the function definition.  (Similar to an extension function.)
Effectively, the receiver becomes a hidden first parameter to the function; as you discovered, if you try to call the function directly, you'll need to give it explicitly.
The language spec for it is here; some other answers may also help.

Migrate Java Option call to kotlin

I'm taking my first steps with kotlin.
I am migrating some my existing java code to kotlin.
I have the folllowing line:
storyDate.ifPresent(article::setPublishDate);
Where storyDate is an Optional and article has a method setPublishDate(Date) method.
How would I migrate this line to kotlin?
The auto migrator at https://try.kotlinlang.org is
storyDate.ifPresent(Consumer<Date>({ article.setPublishDate() }))
But this line doesn't compile with the kotlin compiler.
I strongly prefer using extension functions and extension fields, so I've written smth like
val <T> Optional<T>.value: T?
get() = orElse(null)
And then you can use it anywhere (after import) like
myOptional.value?.let {
// handle here
}
It’s rather uncommon to use Optional in Kotlin. If you can make storyDate work as an ordinary unwrapped type, such constructs can often be expressed with a simple let call:
storyDate?.let {
article.setPublishDate(it)
//probably property access works as well:
article.publishDate = it
}
How it works: The safe call ?. will invoke let only if storyDate is not null, otherwise the whole expression evaluates to, again, null. When the variable is not null, let is called with a simple lambda where storyDate is accessible by it (or you can rename it to whatever you like).
Side note:
If storyDate really must be Optional, you can still use the depicted construct by unwrapping it like this:
storyDate.orElse(null)?.let {}
storyDate.ifPresent { Article.setPublishDate(it) }
or
storyDate.ifPresent(Article::setPublishDate)
will work.
In the first example, it denotes the value in the optional instance, which is the Date in the optional storyDate.
I assumed that Article is a class, which has the setPublishDate(Date) static method, because class names are always capitalized.
But if article is an instance, not a class, and it has non-static method, then the following will work.
// article = Article(/* some Article-typed object */)
storyDate.ifPresent { article.setPublishDate(it) }
it has the same meaning as the above one, i.e., the actual Date value in Optional.

Explanation on Function literal with receiver in Kotlin

I was following this link https://kotlin.link/articles/DSL-builder-in-Kotlin.html to understand the builder implementation in Kotlin. I didn't understand the methods inside Builder class. Method name() receives Extension Function as an argument which receives nothing and returns String. And the caller calls name { "ABC" }. If the caller is passing String to name method, how does it translate to an Extension method which returns String ?
I tried following Kotlin documentation for Function literals with receivers but all had samples which returns Unit or refers to DSL Builders. Tried googling it as well to understand but no luck in grasping the concept.
The call to name { "ABC" } is a combination of two Kotlin conventions.
There is a convention that if the last parameter to a function is a function you can omit the parenthesis. Also since there are no parameters to the lambda, "ABC" is what is returned by it.
So the caller is actually passing a lambda in the form name ({() -> "ABC"}), rather than a String.
Looking at the example in the link, it doesn't look like the receiver is necessary for name(), which is why it could be misleading.