小编Mar*_*ťko的帖子

重载枚举类的强制转换运算符

在我的项目中,我使用了多个枚举类,我需要根据需要在何处使用它们轻松地在它们之间进行转换。它们基本上描述相同的东西,但命名不同,以使代码更易于使用。以下是枚举类:

enum class tetroType {
    None, I, O, T, J, L, S, Z
};

enum class gridBlock {
    Empty, Blue, Green, Orange, Purple, Red, Teal, Yellow
};
Run Code Online (Sandbox Code Playgroud)

tetroType 中的每个值都对应于 gridBlock 中的一个值(fe tetroType::I = gridBlock::Teal),但第一个包含有关 tetronimo 形状的信息(在 tetronimo 类中),第二个包含有关块颜色的信息(在网格类)。我知道我可以只使用一个枚举,但这样你就不会丢失任何信息。如果可能的话,我还需要将其转换为字符串。这就是我想使用它的方式:

gridBlock grid = (gridBlock)tetroType::I;
string texture = (string)grid;
Run Code Online (Sandbox Code Playgroud)

现在我设置它的方式是这样的。每当我需要将一个枚举转换为另一个枚举或字符串时,我都会在其他方法的中间使用此开关:

switch (type) {
case tetroType::I:
    block = gridBlock::Teal;
    break;
case tetroType::O:
    block = gridBlock::Yellow;
    break;
case tetroType::T:
    block = gridBlock::Purple;
    break;
case tetroType::J:
    block = gridBlock::Blue;
    break;
case tetroType::L:
    block = gridBlock::Orange;
    break; …
Run Code Online (Sandbox Code Playgroud)

c++ enums casting c++11

8
推荐指数
2
解决办法
9070
查看次数

使用 sass 可切换自定义引导主题

我能够找到许多不同的方法来了解如何在 SASS 中制作可切换主题,但我无法弄清楚如何将该方法应用于引导程序覆盖。假设我想要浅色和深色主题,并且这两个主题都会以不同的方式覆盖引导颜色。

// Light-theme
$theme-colors: (
    "primary": #8A2F4F
);

// Dark-theme
$theme-colors: (
    "primary": #fff
);
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,覆盖了primaryof theme-colors。如何根据用户选择的主题有条件地设置它们?

css themes sass bootstrap-4

5
推荐指数
1
解决办法
2708
查看次数

std::Optional 与“未使用/默认”值的使用

我正在编写一个代表按钮的类。该按钮可能有也可能没有各种属性,例如上面写的文本、快捷方式、纹理或平面颜色填充。因此,例如,如果此按钮没有任何纹理集,则跳过纹理绘制过程。

我的第一个解决方案是使用虚构的默认值,这表示给定的属性未使用(如果颜色的 alpha 值为 0,则将跳过颜色填充绘图等)。

我的其他选择是使用新添加的 std::Optional ,这会更清晰且更易于使用。

以下是提到的 2 个示例:

class Button {
    void draw() {
        if (fill)
            drawRectangle(*fill);
        if (sprite)
            drawSprite(*sprite);
        if (font)
            drawText(name, *font);
    }

    std::optional<std::string> font;
    std::optional<std::string> sprite;
    std::optional<Color> fill;
}

class Button {
    void draw() {
        if (fill.alpha != 0)
            drawRectangle(fill);
        if (sprite != "")
            drawSprite(sprite);
        if (font != "")
            drawText(name, font);
    }

    std::string font;
    std::string sprite;
    Color fill;
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下使用 std::Optional 的优点和缺点是什么?我主要感兴趣的是内存使用和开销差异。

另外,我是否应该调用 value() 并捕获异常,而不是使用 if 来检查可选是否包含值?

c++ option-type c++17

4
推荐指数
1
解决办法
2262
查看次数

从有区别的联合数组中查找的窄返回类型

我经常使用下面示例中的代码,并且想知道是否有一些聪明的方法来输入find结果而不必进行显式类型断言。

type Foo = { type: "Foo" };
type Goo = { type: "Goo" };
type Union = Foo | Goo;

const arr: Union[] = [];
const foo = arr.find(a => a.type === "Foo") as Foo;
Run Code Online (Sandbox Code Playgroud)

如果as Foo省略类型断言,则结果是 type ,Union即使它只能返回 type Foo

find在这些示例中,修复类型以返回缩小类型的最简洁方法是什么?

编辑:这个问题也适用于filter和其他类似的方法。

Edit2:建议类似问题的已接受答案(Way to tell TypeScript compiler Array.prototype.filter 从数组中删除某些类型?)表明通过在谓词中使用类型保护find/filter可以缩小返回值的范围。

如果例如区分字符串文字总是在type键下,这个类型保护函数应该如何缩小任何可区分的联合?

type-conversion discriminated-union typescript

4
推荐指数
4
解决办法
894
查看次数

将枚举更改为下一个值[C++ 11]

我想要做的是使用枚举轻松指定不同的绘制模式.到目前为止,这就是我所拥有的:

class Grid {
   enum drawMode { GRID, EROSION, RIVERS, HUMIDITY, ATMOSPHERE }
   drawMode activeDraw;

   void draw() {
      switch(activeDraw) {
      case GRID:
         drawGrid();
         break;
      case EROSION:
         drawErosion();
         break;
      // etc..
   }

   void keyPressed(int key) {
      switch(key) {
      case ' ':
         // Cycle activeDraw to next drawMode
      }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果用户点击空格键,activeDraw将从枚举更改为下一个值.因此,如果当前activeDraw是打空格后GRID它将改变糜烂,如果activeDraw是大气它将改变电网.
有一个简单的解决方案吗?谢谢.

c++ enums switch-statement c++11

3
推荐指数
2
解决办法
5678
查看次数

Typescript 基于条件类型的扩展行为不符合预期

假设我们有这个例子:

class Base<T extends Base<T>> {}
class ClassA extends Base<ClassA> {}
class ClassB extends Base<ClassB> {}
type Condition = ClassA extends ClassB ? true : false;
Run Code Online (Sandbox Code Playgroud)

基类有一个通用参数,它基本上说,从它派生的任何东西都应该使用它自己的类型对其进行模板化。

然后我们有 2 个从所述基派生的类。

最后,我创建了一个条件类型来检查派生类是否相互扩展。

令我惊讶的是,打字稿告诉我确实如此,但我认为这个条件应该是错误的。ClassA不延伸ClassB,反之亦然。只ClassA extends Base<ClassA>应该返回true。

这是打字稿条件类型的问题还是我遗漏了什么?我在构建更复杂的条件类型时遇到了这个问题,它也返回了意外的结果。

编辑:也不需要通用参数。即使这个例子也返回错误的结果:

class Base {}
class ClassA extends Base {}
class ClassB extends Base {}
type Condition = ClassA extends ClassB ? true : false;
Run Code Online (Sandbox Code Playgroud)

type-inference typescript typescript-generics conditional-types

2
推荐指数
1
解决办法
5701
查看次数

从键的联合创建对象类型

我了解keyof运算符以及如何创建由该对象的键组成的联合类型,如下所示:

interface Foo {
  a: string;
  b: string;
}

type Goo = keyof Foo; // "a" | "b"
Run Code Online (Sandbox Code Playgroud)

我想做完全相反的事情,并从键的联合创建一个新的对象类型。

const MakeTuple = <T extends string[]>(...args: T) => args;
const Types = MakeTuple("A", "B", "C");
type TypeVariant = typeof Types[number];

type VariantObject = {
  // This gives error consider using a mapped object but I'm not sure how to do that
  [type: TypeVariant]: [boolean, boolean, boolean, string[]];
}
Run Code Online (Sandbox Code Playgroud)

所以我想要的是采用键的联合并生成一个类型,其中包含 type 的每个键的值[boolean, boolean, boolean, string[]]

typescript

2
推荐指数
1
解决办法
1629
查看次数

具有多个条件的 Typescript 条件映射类型

我正在 redux 存储中处理规范化数据(所有复杂类型只是引用真实对象的 id),并且我想使用 typescript 的条件映射类型功能创建非规范化类型。

我保留 id 所引用的对象的实际类型,因为它是通用参数,并且如果仅使用非数组 id 属性,我就能够正确创建非规范化类型。

type Id<T extends HandlerBase<any>> = string & { __type: T };

class HandlerBase<T extends HandlerBase<T>> {};

class HandlerA extends HandlerBase<HandlerA> {
    str: string;
    b: Id<HandlerB>;
    bArr: Id<HandlerB>[];
};

class HandlerB extends HandlerBase<HandlerA> {};

type DenormalizedHandler<T> = {
    [P in keyof T]: T[P] extends Id<infer U> ? DenormalizedHandler<U> : T[P];
}

const handler: DenormalizedHandler<HandlerA> = undefined;
handler.str; // Is string
handler.b; // Is DenormalizedHandler<HandlerB>
handler.bArr; // Should be DenormalizedHandler<HandlerB>[]
Run Code Online (Sandbox Code Playgroud)

现在我需要弄清楚如何添加第二个条件,以便 …

typescript typescript-generics

2
推荐指数
1
解决办法
7896
查看次数