代码之家  ›  专栏  ›  技术社区  ›  adelarsq

对Scala使用C联合

  •  2
  • adelarsq  · 技术社区  · 14 年前

    是否可以使用Scala模拟C联合结构?在这种情况下,变量会相互覆盖。

    1. 同一个变量允许使用不同的类型。
    2. 变量使用相同的内存位置。

    我认为第二个特点是最难模仿的。

    谢谢

    4 回复  |  直到 14 年前
        1
  •  6
  •   user166390 user166390    14 年前

    一般来说 case classes 创造 discriminated (tagged) unions

    在case类教程中,您可以看到Var,Fun应用程序都可以存储在能够保存一个术语的东西中。那么 pattern matching 可用于提取已存储的内容并根据 (变量、乐趣、应用程序等)匹配。整个过程类似于使用额外的“type”标志,if/else构造通常只与C联合使用,同样,类型安全(而且在大多数情况下更方便:-)

    使用Scala的实例/说明: What is an algebraic data type? 它还很好地展示了它是如何关联的/是如何用“较少的”语言处理的。

        2
  •  3
  •   Daniel C. Sobral    14 年前

    我想你最好的选择是 Either :

    var x: Either[Int, Double] = _
    x = Left(5)
    x = Right(1.5)
    x match {
        case Left(i) => println("Int "+i)
        case Right(d) => println("Double "+d)
    }
    

    让你做的是“读”一种类型,就好像它是另一种。它使用的引用确实比单独使用的类型的大小多,但它不会将两种类型的大小相加。它允许您知道存储的是哪种类型。

        3
  •  1
  •   Kevin Wright    14 年前

    要在Java中(因此在Scala中)执行等效操作,您应该查看NIO库: http://en.wikipedia.org/wiki/New_I/O

    相反,如果您对这个API更满意,那么您可以使用旧的Reader/Writer/Stream方法(http://tutorials.jenkov.com/java-io/index.html),并且您可能会在那里找到更多的在线教程。

        4
  •  1
  •   user unknown    13 年前

    如果编写一个类型参数化类联合,使用a=>B和B=>a中的隐式转换器

    class Union [A, B] {
      getA = ...
      getB = ...
    }
    

    class Union [A, B, C] (c: C) (implicit 
      a2c: (A => C), 
      b2c: (B => C),  
      c2a: (C => A), 
      c2b: (C => B)) {
      def getA : A = c2a (c) 
      def getB : B = c2b (c)
    }
    

    As和Bs存储为Cs,并且有一个方法,a和B分别从C中获取值。

    为了使用它,我们采用了一些演示方法:

    def l2i (l: List[Char]): Int = 
      (0 /: l.reverse.take (4).reverse) ((a, b) => (a * 255 + b))
    def i2l (i: Int): List[Char] = 
      if (i < 255) List (i.toChar) else (i % 255).toChar :: toChars (i / 255)
    def l2s (l: List[Char]): String = 
      l.mkString ("")
    def s2l (s: String): List[Char] = 
      s.toCharArray.toList
    

    然后我们创建一个真正的联合(String/Int/List):

    class UnionSIL (l: List[Char]) 
      extends Union [String, Int, List[Char]] 
        (l: List[Char]) (s2l, i2l, l2s, l2i) {
      def this (i: Int) = this (i2l (i))
      def this (s: String) = this (s2l (s))
    }
    

    val ui = new UnionSIL (44) 
    val us = new UnionSIL ("foobar") 
    List(ui, us).foreach (u => println (u.getA + ": " + u.getB)) 
    
    ,: 44
    foobar: 1846929924