A couple examples in the Kotlin extension functions docs show array literals that aren’t valid in Kotlin. E.g.:
FullTextIndexConfigurationFactory.create(expressions = ["name","location"])
This would be a valid array literal in Swift, but not Kotlin. Valid use would be either
FullTextIndexConfigurationFactory.create(expressions = arrayOf("name", "location"))
or without the named parameter
FullTextIndexConfigurationFactory.create("name", "location")
which wouldn’t be much different than the constructor.
I also had a question about the goal of the factory extension APIs. The docs state
these allow use of named parameters
So instead of
FullTextIndexConfiguration("name", "location")
you can do
FullTextIndexConfigurationFactory.create(expressions = arrayOf("name", "location"))
Is this the only goal, to create an API that allows explicitly using named parameters to construct objects?
The docs also allude to another potential feature of these extension functions, which is
overriding the receiver’s values with the passed parameters
But none of the examples actually show the API being used this way, always calling the API from the *Factory
variables, which are null
and wouldn’t have any receiver values to override.
You could also use the extension function to create a copy of an existing object, overriding some of the parameters. E.g.
val config1 = LogFileConfiguration("dir")
.setMaxSize(10_000)
.setMaxRotateCount(5)
.setUsePlaintext(true)
val config2 = config1.create(
maxRotateCount = 10
)
But not all the extensions would make sense to use this way, if the object doesn’t have multiple constructor parameters or if any of their properties aren’t constructor parameters, like the IndexConfiguration
s.
It wouldn’t make sense to
val index1 = FullTextIndexConfiguration("name", "location")
.ignoreAccents(true)
val index2 = index1.create(expressions = arrayOf("age", "occupation"))
since index2
overrides the only parameter it could have received from index1
. This could also be misleading, since the ignoreAccents
value is not actually copied to index2
.
I’m not sure there’s value in copying the object without modifying any parameters either.
val index1 = FullTextIndexConfiguration("name", "location")
.ignoreAccents(true)
val index2 = index1.create()
as this just results in index2
having index1
’s expressions, but returning ignoreAccents
to its default value of false.
If this second usage of copying parameters from one object to another isn’t a goal for an extension API, it could be prevented by making the factory an object, instead of a variable with an extension function. E.g.
object FullTextIndexConfigurationFactory {
fun create(
vararg expressions: String
) = FullTextIndexConfiguration(*expressions)
}
This would allow for the named parameter API usage, but prevent calling with an existing object as the receiver.