admin管理员组

文章数量:1317898

How do I get types from compound or the ancestors of derived objects?

For example, how do I get string from the following arg?

proc MyProc(theArg: Table[string, int]) =
  var innerKey: typeof(theArg)[0] # trying to get string from theArg
  var innerVal: typeof(theArg)[1] # trying to get int from theArg
  ...
  

Above example is silly because obvs I'm already typing string and int.

The real case is closer to something like this:

type
  SomeEnum = enum Up, Down, Left, Right, Sideways`
  MyKeyType = string
  MyValType = SomeEnum
  BigTable = Table[MyKeyType, MyValType]

proc MyProc(table: BigTable): =
  var innerKey: ...? # find the key type of BigTable
  var innerVal: ...? # find the val type of BigTable
  var someThing: ...? # find the ancestor or root+1 ancestor of MyValType, ie SomeEnum (not RootObj)
  ...

How do I get types from compound or the ancestors of derived objects?

For example, how do I get string from the following arg?

proc MyProc(theArg: Table[string, int]) =
  var innerKey: typeof(theArg)[0] # trying to get string from theArg
  var innerVal: typeof(theArg)[1] # trying to get int from theArg
  ...
  

Above example is silly because obvs I'm already typing string and int.

The real case is closer to something like this:

type
  SomeEnum = enum Up, Down, Left, Right, Sideways`
  MyKeyType = string
  MyValType = SomeEnum
  BigTable = Table[MyKeyType, MyValType]

proc MyProc(table: BigTable): =
  var innerKey: ...? # find the key type of BigTable
  var innerVal: ...? # find the val type of BigTable
  var someThing: ...? # find the ancestor or root+1 ancestor of MyValType, ie SomeEnum (not RootObj)
  ...
Share Improve this question edited Jan 22 at 19:13 Sonicsmooth asked Jan 22 at 16:07 SonicsmoothSonicsmooth 2,7772 gold badges24 silver badges40 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 0

The short answer is: you don't, because your example doesn't make much sense as it is not using generics. If you aren't using generics, you already know at write time everything you need about the type of your parameters. And in the case of a proc using generics you would probably not need to specify the type and use type inference anyway.

In general your example doesn't compile at the basic level, HashSet doesn't allow an array style invocation. I believe you are missing the brackets typical of a tuple (Hashset[(string, int)]), but it's hard to predict what you actually want of your example. Maybe you are trying to write a macro?

This is what I came up with using generics. Not sure if this is what the commenter had in mind. I can pass in different types of Tables and I get the correct output.

How do I resolve MyKeyType to float ?

import std/strformat
import std/tables

type 
  Rect = ref object
    x: int
    y: int
  RectTableStringKey = Table[string, Rect]
  RefRectTableStringKey = ref Table[string, Rect]

  MyKeyType = float
  MyValueType = string

  XTableYKey = Table[MyKeyType, MyValueType]
  RefXTableYKey = ref Table[MyKeyType, MyValueType]

proc `$`[K,V](table: Table[K,V]): string = 
  result = fmt"hello from $Table[{$K}, {$V}]"

proc `$`[K,V](table: ref Table[K,V]): string = 
  result = fmt"hello from $refTable[{$K}, {$V}]"

var myTable1: RectTableStringKey
myTable1["one"] = Rect(x:10, y:20)
myTable1["two"] = Rect(x:15, y:25)

var myTable2: RefRectTableStringKey
new myTable2
myTable2["three"] = Rect(x:99, y:100)
myTable2["four"]  = Rect(x:909, y:109)

var myTable3: XTableYKey
myTable3[3.14159] = "hello"
myTable3[2.78183] = "bye"

var myTable4: RefXTableYKey
new myTable4
myTable4[1.2345] = "dog"
myTable4[9.9998] = "horse"


echo myTable1
echo myTable2[]
echo myTable3
echo myTable4[]

Output:

hello from $Table[string, Rect]
hello from $Table[string, Rect]
hello from $Table[MyKeyType, MyValueType]
hello from $Table[MyKeyType, MyValueType]

本文标签: nim langHow to get type information from HashSet and derived type (aka ancestors)Stack Overflow