kotlin getters and setters expecting member declaration error? - kotlin

I'm starting to learn kotlin but I having problem implementing getters and setters I searched online and the code for my getters and setters is the same used by many guides.
package com.test
import kotlin.Int
class Test{
var name: Int = 10;
get(){
println("getting value");
return field;
}
set(value){
println("setting value");
field = value;
}
}
fun main() {
val test = Test();
println(test.name);
}
I cant see whats wrong in this code that make kotlin compiler emit an error. I'm compiling using kotlinc proj.kt.

You seem to really like adding semicolons, and you try to add them everywhere. However, you added them too early in this case:
var name: Int = 10;
get(){
println("getting value");
return field;
}
set(value){
println("setting value");
field = value;
}
This whole thing declares a property called name, so there should not be a semicolon after var name: Int = 10.
Your wrongly-added semicolon makes the parser think that the declaration for name ends there, and so the parser expects another declaration after that. Instead of another declaration, you wrote get() { ..., which only makes sense to the parser when you are declaring a property, but as far as the parser is concerned, you are not declaring a property at this point, as the declaration of name is already finished by your semicolon.
If you must add a semicolon, it would be after the } of set(value), like this:
var name: Int = 10
get(){
println("getting value");
return field;
}
set(value){
println("setting value");
field = value;
};
See also the grammar for a property declaration.
However, note that Kotlin coding convention says that you should omit semicolons whenever possible, so you should omit all your semicolons, like this:
var name: Int = 10
get(){
println("getting value")
return field
}
set(value){
println("setting value")
field = value
}

Related

How to call constructor default lambda using Kotlin Refelction?

Trying to call lambda provided by MyClass constructor using Kotlin Reflection.
data class MyClass(
var magic:Int=2,
var lambdaValue: ()->String = { //trying to call this lambda from reflection
"Working"
},
)
fun main(args: Array<String>) {
val clazz=MyClass::class
val obj=clazz.createInstance()
val kProperty=clazz.memberProperties
clazz.constructors.forEach{cons-> // for each construtor
cons.parameters.forEach{ parameter-> // looping through constructor parameters
val property=kProperty.find { it.name==parameter.name } // finding the exact property
print(parameter.name+" : ")
if(parameter.type.arguments.isEmpty()) // if empty Int,Float
{
println(property?.get(obj))
}else{
println(property?.call(obj)) // unable to call lambda
}
}
}
}
property.call(obj) returns Any which is not invokable. Any solution?
Expected:
magic : 2
lambdaValue : Working
Frankly speaking, I'm not sure what was your idea behind parameter.type.arguments.isEmpty(). It seems unrelated to what you try to do.
If we have a value of the property already, we can simply check its type and if its is a function then invoke it:
val value = kProperty.find { it.name==parameter.name }!!.get(obj)
print(parameter.name+" : ")
when (value) {
is Function0<*> -> println(value())
else -> println(value)
}
I think usefulness of such a code in generic case isn't very high. This code doesn't know what is the function and if it is going to return a value or perform some action, etc. Maybe in your specific case it is more useful.

Kotlin DSL variable imitation

Using Kotlin type-safe builders one might end up writing this code
code {
dict["a"] = "foo"; // dict is a Map hidden inside that can associate some name to some value
println(dict["a"]); // usage of this value
}
This code is ok, but there is a problem: "a" is just a string. I want it to be like a user-defined variable - an identifier that is recognized by the compiler, auto-complete enabled.
Is there a way to turn it into something like this?
code {
a = "foo"; // now 'a' is not a Map key, but an identifier recognized by Kotlin as a variable name
println(a);
}
I can do this if I make code's lambda an extension function over some object with a field a defined inside. This is not what I want. I want to be able to use other variables (with unknown names) as well.
A possible workaround could be
code {
var a = v("a", "foo");
println(a);
}
Where v is a method of the extension's object, that stores value "foo" inside "dict" and also returns a handle to this value.
This case is almost perfect, but can it be clearer/better somehow?
You can use property delegation:
class Code {
private val dict = mutableMapOf<String, String>()
operator fun String.provideDelegate(
thisRef: Any?,
prop: KProperty<*>
): MutableMap<String, String> {
dict[prop.name] = this
return dict
}
}
Use case:
code {
var a by "foo" // dict = {a=foo}
println(a) // foo
a = "bar" // dict = {a=bar}
println(a) // bar
}

Use an anonymous function when setting the return value for a getter in Kotlin

In Kotlin when you create a getter/setter pair, you typically set the getter using inline code. But I am wondering if it is possible to replace the inline code with an anonymous function:
var UserSettings: UserSettings?
get() = getUserSettings() // Replace this with an anonymous function?
set(value) {
putPref(USER_SETTINGS, Json.stringify(UserSettings.serializer(), value!!))
}
private fun getUserSettings(): UserSettings? {
val info = getPref(KEY_USER_SETTINGS)
return Json.parse(UserSettings.serializer(), info!!)
}
Can the getUserSettings() be replaced with an anonymous function? In the code above I have a separate function getUserSettings that I would like to place right after the get() =
Yes, you can. Just have a look at getters and setters - backing properties, where there is (the first and only example), mentioning get() { instead of get() =. Your sample would then look as follows:
var UserSettings: UserSettings?
get() {
val info = getPref(KEY_USER_SETTINGS)
return Json.parse(UserSettings.serializer(), info!!)
}
set(value) {
putPref(USER_SETTINGS, Json.stringify(UserSettings.serializer(), value!!))
}
i don't know this is what you asking for but it might be helpful
var v: Int? = null
get() = run {
return field
}
set(value) = run {
field = value
}
in this case getter must be equel to Int? and setter allways must be equel to Unit. so in the run we return that types
I think the answer of #Roland is valid.
Be aware that maintaining the = before the anonymous function the compiler returns an error as you are describing.
Can you double check that you are NOT writing something like this?
var UserSettings: UserSettings?
get() = { ... }
And that you are writing:
var UserSettings: UserSettings?
get() { ... }

Kotlin - Understanding Getters and Setters

Kotlin auto-generates it's getters and settings, but I never refer to them? Also, what is the correct way to write a custom getter/setter in Kotlin? When I say myObj.myVar = 99 I feel like myVar is a public field of myObj that I'm accessing directly? What is actually happening here?
This has been answered in a few places, but I thought that I would share a concrete example for people transitioning to Kotlin from Java/C#/C/C++, and who had the same question that I did:
I was having difficulty in understanding how getters and setters worked in Kotlin, especially as they were never explicitly called (as they are in Java). Because of this, I was feeling uncomfortable, as it looked like we were just directly referring to the vars/vals as fields. So I set out a little experiment to demonstrate that this is not the case, and that in fact it is the implicit (auto-generated) or explicit getter/setter that is called in Kotlin when you access a variable/value. The difference is, you don't explicitly ask for the default getter/setter.
From the documentation - the full syntax for declaring a property is:
var <propertyName>: <PropertyType> [= <property_initializer>]
[<getter>]
[<setter>]
And my example is
class modifiersEg {
/** this will not compile unless:
* - we assign a default here
* - init it in the (or all, if multiple) constructor
* - insert the lateinit keyword */
var someNum: Int?
var someStr0: String = "hello"
var someStr1: String = "hello"
get() = field // field is actually this.someStr1, and 'this' is your class/obj instance
set(value) { field = value }
// kotlin actually creates the same setters and getters for someStr0
// as we explicitly created for someStr1
var someStr2: String? = "inital val"
set(value) { field = "ignore you" }
var someStr3: String = "inital val"
get() = "you'll never know what this var actually contains"
init {
someNum = 0
println(someStr2) // should print "inital val"
someStr2 = "blah blah blah"
println(someStr2) // should print "ignore you"
println(someStr3) // should print "you'll never know what this var actually contains"
}
I hope that helps to bring it all together for some others?
Here are some real world examples of custom getters and setters. You can see more here.
// Custom getter example
val friendlyDescription get(): String {
val isNeighborhood = district != null
var description = if (isNeighborhood) "Neighborhood" else "City"
description += " in"
if (isNeighborhood) {
description += " $city,"
}
province?.let {
if (it.isNotEmpty()) {
description += " $it,"
}
}
description += " $country"
return description
}
print(myLocation.friendlyDescription) // "Neighborhood in Denver, Colorado, United States"
// Custom setter example
enum class SearchResultType {
HISTORY, SAVED, BASIC
}
private lateinit var resultTypeString: String
var resultType: SearchResultType
get() {
return enumValueOf(resultTypeString)
}
set(value) {
resultTypeString = value.toString()
}
result.resultType = SearchResultType.HISTORY
print(result.resultTypeString) // "HISTORY"

typescript interface initialization

My level of typescript is 'ABSOLUTE BEGINNER' but I have a good OOP background. I am building an with typescript that reference an external t.ds library that contains the following interface:
interface ISimpleObject {
foo: string;
bar?: any;
}
Now, if I want to call a method that has an IRequestConfig parameter, how do I create one? I can see different options:
Create a simple implementation of ISimpleObject. I don't like this approach because it looks like boilerplate code to me
don't initialize the object (I fear this could break something...):
var x :IsimpleObject;
x.bar = 'xxx';
callMethod(x);
Cast a pojo:
var x :IsimpleObject = <IsimpleObject>{foo: 'yyy', bar:'xxx'};
I don't like this approach either because it doesn't enforce type safety...
I guess this is a fairly trivial question and I am missing something trivial about typescript.
Typescript2:
const simpleObject = {} as ISimpleObject;
If you have an interface like:
interface ISimpleObject {
foo: string;
bar?: any;
}
This interface is only used at compile time and for code-hinting/intellisense. Interfaces are used to provide a rigorous and type-safe way of using an object with a defined signature in a consistent manner.
If you have a function using the interface defined above:
function start(config: ISimpleObject):void {
}
The TypeScript compile will fail if an object does not have the exact signature of the ISimpleObject interface.
There are multiple valid techniques for calling the function start:
// matches the interface as there is a foo property
start({foo: 'hello'});
// Type assertion -- intellisense will "know" that this is an ISimpleObject
// but it's not necessary as shown above to assert the type
var x = <ISimpleObject> { foo: 'hello' };
start(x);
// the type was inferred by declaration of variable type
var x : ISimpleObject = { foo: 'hello' };
start(x);
// the signature matches ... intellisense won't treat the variable x
// as anything but an object with a property of foo.
var x = { foo: 'hello' };
start(x);
// and a class option:
class Simple implements ISimpleObject {
constructor (public foo: string, public bar?: any) {
// automatically creates properties for foo and bar
}
}
start(new Simple("hello"));
Any time the signature doesn't match, the compile will fail:
// compile fail
var bad = { foobar: 'bad' };
start( bad );
// compile fail
var bad: ISimpleObject = { foobar: 'bad' };
// and so on.
There is no "right" way to do it. It's a matter of style choice. If it were an object that was constructed (rather than just directly passed as a parameter), I'd normally declare the type:
var config: ISimpleObject = { foo: 'hello' };
That way code-completion/IntelliSense will work anywhere I used the config variable:
config.bar = { extra: '2014' };
There is no "casting" in TypeScript. It is called a type assertion and shouldn't be needed in the cases described here (I included an example above where it could be used). There's no need to declare the variable Type and then use an assertion in this case (as the type was already known).
You can't create an instance of an interface since Typescript doesn't "translate" it into js. You can check the js that is created and you will see nothing in it. It's simple for compile errors, type safety and intelisense.
interface IStackOverFlow
{
prop1 : string;
prop2 : number;
}
public MyFunc(obj : IStackOverFlow)
{
// do stuff
}
var obj = {prop1: 'str', prop2: 3};
MyFunc(obj); // ok
var obj2 = {prop1: 'str'};
MyFunc(obj); // error, you are missing prop2
// getObj returns a "any" type but you can cast it to IStackOverFlow.
// This is just an example.
var obj = <IStackOverFlow> getObj();