简体   繁体   中英

Kotlin accessing variable from other class not by name directly but by string variable

I'm trying to access a variable from another class. The usual way would be:

in Class A

var something = ClassB().element

in Class B

val element = "hi"

Is it also possible to address element not by its name directly, but when I have the name stored in a string? So I have a string that holds

var name = "element"

and want to do something like

var something = ClassB().name //(this doesn't work)

The reason I'm asking is because I have a class in which I do some pitch processing and another class in which I store all of my pitch data in float arrays (the Hz values of different musical notes for different tunings of different instruments)

In the class I do my pitchprocessing in I want to select the right float array depending on a user selection (made with a spinner), which I "translate" with a map (so for example the spinner says "Standard Tuning" and the according array would be called "guitarStandard", in my map "Standard Tuning" would be the key and "guitarStandard" the according value). To not hardcode the different cases in which I need different arrays with if statements, I simply want the name of the array stored in a string by getting the correct value of my map and adress it that way.

I feel like that should be either super simpel or I'm thinking about it the completely wrong way, can someone help out? Thanks

I would advise that you don't store a list of strings, and instead store a list of lambdas that return property values:

class Foo {
    val prop1 = arrayOf(1.0, 2.0, 3.0)
    val prop2 = arrayOf(4.0, 5.0, 6.0)
}

fun main() {
    val props: List<(Foo) -> Array<Double>> = listOf({it.prop1}, {it.prop2})
    val foo = Foo()
    for (prop in props) {
        println(prop(foo).toList())
    }
}

But, if you wanted to search up property names from a string, you should look into reflection .

I'd suggest to refactor your ClassB by extracting those properties to separate enum class:

enum class Tunes(vararg f: Float) {
    TUNE1(1.0f, 2.0f, 3.0f), TUNE2(4.0f, 5.0f, 6.0f);

    val frequencies: FloatArray = f
}

That will make your mapping more straightforward and won't involve reflection:

import Tunes.*

val mapping = mapOf("Standard Tuning" to TUNE1, "Alternate Tuning" to TUNE2)
val result = mapping[userInput]?.frequencies

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM