Kotlin的方法是什么,它与C#中的flags enum变量具有类似的效果

pkwftd7m  于 2023-05-23  发布在  Kotlin
关注(0)|答案(4)|浏览(98)

在C#中,我们可以这样做。

[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);
}

在Kotlin中,似乎我不能“或”两个标志。Kotlin是如何做到这一点的?使用枚举变量列表?

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);
}

补充:谢谢你的回答(由于时间限制,我还不能标记为答案)。我修改了下面的代码,实现了我想要的。

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);
}
0s7z1bwu

0s7z1bwu1#

使用扩展函数

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)
}

我使用扩展函数来允许添加属性,并使用和allof来检查是否设置了所有标志。

ggazkfy8

ggazkfy82#

事实上,在Kotlin中,每个枚举常量都是对应于该枚举的类的示例,并且不能使用'OR'来合并多个类示例。如果需要跟踪多个枚举值,最有效的方法是使用EnumSet class

vmpqdwk3

vmpqdwk33#

通过这种方式,可以实现与C#枚举标志相同的结果

enum class TestType(val value: Int)
{
    x(1),
    y(2),
    z(4)
}

fun Int.hasFlag(flag: Int): Boolean
{
    return ((this and flag) == flag)
}

使用方法:

val myType = TestType.x.value or TestType.y.value //myType = 3

println(myType.hasFlag(TestType.x.value)) //true

println(myType.hasFlag(TestType.y.value)) //true

println(myType.hasFlag(TestType.z.value)) //false

println(myType.hasFlag(TestType.x.value or TestType.y.value)) //true

println(myType.hasFlag(TestType.x.value or TestType.z.value)) //false
wydwbb8l

wydwbb8l4#

我有一个简单的enum类:

enum class Border(val value: Int) {
    None(0),

    Left(1),
    Top(2),
    Right(4),
    Bottom(8),
}

我创造了一个类似于[Flags] enum的东西:

class Borders {

    private var value = Border.None.value

    fun add(border: Border) {
        value = value.or(border.value)
    }

    fun has(border: Border) =
        value.and(border.value) == border.value

    fun del(border: Border) {
        value = value.and(border.value.inv())
    }
}

现在我可以使用:

class BordersTests {

    @Test
    fun test01() {

        val borders = Borders()
        Assert.assertEquals(borders.has(Border.Top), false)

        borders.add(Border.Top)
        Assert.assertEquals(borders.has(Border.Top), true)

        borders.del(Border.Top)
        Assert.assertEquals(borders.has(Border.Top), false)
    }
}

相关问题