Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is Kotlin's way to have similar effect as flags enum variable in C#

Tags:

kotlin

In C#, I can do this.

[Flags]
enum BeerProperty
{
    Bold = 1,
    Refreshing = 2
}

static void Taste(BeerProperty beer)
{
    if (beer == (BeerProperty.Bold | BeerProperty.Refreshing))
    {
        Debug.WriteLine("I can't qutie put my finger on...");
    }
}

static void Main(string[] args)
{
    var tickBeer = BeerProperty.Bold | BeerProperty.Refreshing;
    Taste(tickBeer);
}

In Kotlin, it seems that I cannot "OR" two flags. What is the Kotlin's way to do this? Using a list of enum variables?

enum class BeerProperty(value:Int)
{
    Bold(1),
    Refreshing(2)
}

fun taste(beer:BeerProperty)
{
    if(beer == (BeerProperty.Bold | BeerProperty.Refreshing))
    {
        print("I can't qutie put my finger on...");
    }
}

fun main(args: Array<String>)
{
    val tickBeer = BeerProperty.Bold | BeerProperty.Refreshing;
    taste(tickBeer);
}

Added: Thank you for the answer (which I cannot mark as answer yet, due to time limitation). I modified the code like below and achieved what I wanted.

fun taste(beer: EnumSet<BeerProperty>)
{
    if(beer.contains(BeerProperty.Bold) && beer.contains(BeerProperty.Refreshing))
    {
        print("I can't qutie put my finger on...");
    }
}

fun main(args: Array<String>)
{
    val tickBeer = EnumSet.of(BeerProperty.Bold, BeerProperty.Refreshing);
    taste(tickBeer);
}
like image 374
Damn Vegetables Avatar asked Mar 12 '18 11:03

Damn Vegetables


2 Answers

Using extension functions

import java.util.*

enum class BeerProperty
{
    BOLD,
    REFRESHING,
    STRONG;

    infix fun and(other: BeerProperty) = BeerProperties.of(this, other)
}

typealias BeerProperties = EnumSet<BeerProperty>

infix fun BeerProperties.allOf(other: BeerProperties) = this.containsAll(other)
infix fun BeerProperties.and(other: BeerProperty) = BeerProperties.of(other, *this.toTypedArray())

fun taste(beer: BeerProperties) {
    if(beer allOf (BeerProperty.BOLD and BeerProperty.REFRESHING and BeerProperty.STRONG)) {
        print("I can't qutie put my finger on...")
    }
}

fun main(args: Array<String>) {
    val tickBeer = BeerProperty.BOLD and BeerProperty.REFRESHING and BeerProperty.STRONG
    taste(tickBeer)
}

I use extension functions to allow properties to be added with and, and allof to check all flags are set.

like image 92
jrtapsell Avatar answered Sep 28 '22 18:09

jrtapsell


Indeed, in Kotlin every enum constant is an instance of the class corresponding to the enum, and you can't use 'OR' to combine multiple clas instances. If you need to track multiple enum values, the most efficient way to do that is to use the EnumSet class.

like image 38
yole Avatar answered Sep 28 '22 17:09

yole