Kotlin - Using Enums to retrieve a Char - enums

Being a little new to OOP concepts, enums in Kotlin are a bit confusing to me. My caveman interpretation is that enums are used to store non changing variables. I'm making a simple Tic-Tac-Toe app and simply want to store the values 'X', 'Y', and '-' all as Chars. Where is my confusion? Is there a better way to retrieve a particular set of Chars from a "library"? Here is my current assumption in code:
enum class markers(char: Char){
X('X'), O('O'), EMPTY('-')
}
//To access the enums, thought it would be something like this
fun printX(){
println(markers.X)
}

You want to have the property char instead of the enum constants‘ name, change to:
fun printX(){
println(markers.X.char)
}
Also make char a val so that it’s accessible as a property: enum class markers(val char: Char)

enum class markers(private val char: Char){
X('X'), O('O'), EMPTY('-');
override fun toString() = char.toString()
}
markers.values().forEach(::print)

Related

Validate at least 1 of a set of args is present in Kotlin class constructor

Scenario
I need to create a Kotlin class that can receive up to 4 arguments for its constructor, but only requires at least 1 out of a set of 3 (the fourth being entirely optional). To illustrate:
class Pie {
// Completely optional, the constructor should use it if present, otherwise it may be null.
var topping: String?
// Of these three [fillingA, fillingB, fillingC] 1 or more must be present.
var fillingA: String?
var fillingB: String?
var fillingC: String?
}
Thoughts
I've attempted to use Kotlin init{} blocks for validation, or telescoping constructors, but it gets ugly fast and I've yet to solve the issue. I have not found anything in the kotlinlang.org docs on primary/secondary constructors that is more elegant, though. My preference would be to find something similar to the #Size or #NotNull annotations, but I have failed to locate anything close.
It is important to note that I am using this class as a model for an API response.
Question
What is the most concise way to validate that a Kotlin class has at least 1 of a set of arguments passed to its constructor?
Are this fillings interchangeable? You could assume that fillingA is always required and the other ones are optional, something like this:
class Pie constructor(
val fillingA: String,
val fillingB: String? = null,
val fillingC: String? = null,
val topping: String? = null
){...}

Enums in GraphCool? How to use them? No Documentation

GraphCool doesn't have much documentation on Enums, so I am just posting my Enum info for those who could use it:
Enums are arguments of an object that can only have specified values. GraphCool also, to my knowledge, requires them to be defined with a default value.
An example Enum is (write them in the enums tab):
enum PublishersEnum {
PEARSON
WILEY
MCGRAWHILL
}
An example type with enum:
type Book {
...
publisher: PublishersEnum #defaultValue(value: PEARSON)
...
}
Recommendations/conventions:
Use all caps to help distinguish enum usage.
Name the enum with "Enum" in the name somewhere
Concerns:
I have not had good luck with the graph cool interface, when I try to migrate from a string to an enum, the migration value and such didn't work well, hopefully others will have better luck.

Enums and With in Kotlin

Either my syntax is wrong, or you can't use with to apply to enum constants. IntelliJ says it's because RegexOption doesn't have a companion object, and that RegexOption needs to be initialized here. I didn't think you could instantiate an enum.
// this works:
val RX_OPTIONS = mapOf(
'c' to RegexOption.COMMENTS,
'd' to RegexOption.DOT_MATCHES_ALL,
'e' to RegexOption.CANON_EQ,
'i' to RegexOption.IGNORE_CASE,
'l' to RegexOption.LITERAL,
'm' to RegexOption.MULTILINE,
'u' to RegexOption.UNIX_LINES
)
// this doesn't work:
val RX_OPTIONS2 = with(RegexOption) { mapOf(
'c' to COMMENTS,
'd' to DOT_MATCHES_ALL,
'e' to CANON_EQ,
'i' to IGNORE_CASE,
'l' to LITERAL,
'm' to MULTILINE,
'u' to UNIX_LINES
) }
Why doesn't the second example work? If they're not in the companion object, it doesn't seem like they'd be in an instance. Does with have a counterpart that could work in this situation? If not, is it easy to write one (since with is just a one-liner)?
EDIT (Refining the question):
In a block (not necessarily even this one) where I'm typing 20 references to the same long enum names like Class.Inner.VeryInner.YouGetTheIdea.SOMEOPTION is it possible to factor out all but the SOMEOPTION name using a with-statement-like construct just for a block -- even one that I must write myself as a higher order function? I've considered typealias, but I really want this to apply only to the block. The answer below tells me the with higher-order function doesn't work for this, but is there a way to do it?
The one-liner implementation of with is:
public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block()
The T.() is a function literal with a receiver, and the receiver is an object. You're passing a class.
The documentation for Kotlin function literals with receiver can be found here.

Converting between struct types in Go

So I have a question that I've been trying to figure out for a while and hopefully someone has some insight. Basically, I have two similar, but different structs in Go and I would like to convert between them.
Something like the following:
type A struct {
Name string
}
type B struct {
Name NameStruct
}
type NameStruct struct {
Firstname string
Lastname string
}
In this example,
B.Name == NameStruct{
Firstname: strings.Split(A.Name, " ")[0],
Lastname: strings.Split(A.Name, " ")[1],
}
Basically I would like to be able to define a mapping of fields from one struct to the other as well as a conversion function, so that I can do this without writing all of the code to do the conversion manually.
What I'm imagining is that there might be some sort of Go generator out there that could do something like this. I don't think it is possible using reflection because of the nested structs (although I'm open to suggestions).
Basically, does anyone know of a way to do this that is better than either writing conversion code manually or creating my own generator?

enum class in QVariant in QSettings

I have a problem with enum classes, QVariants and the QSettings class. There are enum class values that I want to store within a QVariant which goes into a QSettings instance. So, my code actually looks something like this:
enum class Foo
{
Bar1, Bar2
}
Q_ENUMS(Foo)
Q_DECLARE_METATYPE(Foo)
...
Foo value = Bar2;
QSettings settings;
settings.setValue(QString("Foo"), QVariant::fromValue(value));
At this point in executing the code, an assertion jumps in and complains:
ASSERT failure in QVariant::save: "Invalid type to save", file kernel\qvariant.cpp
Searching the internet, I found out that the class is missing a fitting << and >> operator. But that is not an option for enum classes. I even tried to use
qRegisterMetaType<Foo>("Foo");
but it did not help. Maybe you have some other suggestions/solutions for me. Thanks!
Enums, which are masked unsigned ints, seem to be a problem, see
Qt4 QSettings save enumeration value (for example Qt::CheckState)
The solution there and probably here would be to convert it an unsigned. To check if the static_cast-result back to the enum is valid you might add Foo_lowest and Foo_highest values to the beginning and end of the enum range.
You can use Q_ENUM since Qt 5.5 and not worry about calling qRegisterMetaType():
enum class Foo
{
Bar1, Bar2
}
Q_ENUM(Foo)
...
Foo value = Foo::Bar2;
QSettings settings;
settings.setValue(QString("Foo"), QVariant::fromValue(value));

Resources