Haskell中获取数据类型对应对象键名的最优实现方法是什么?
方案1:保留aeson依赖,去掉多余的编解码往返
你原本的实现需要先把对象序列化为JSON字节串再反序列化为Object,属于无意义的往返操作,既增加了性能开销,还引入了不必要的解码失败分支。直接调用toJSON方法就能拿到JSON结构,匹配出Object后直接取键即可:
{-# LANGUAGE DeriveGeneric #-} import Data.Aeson import GHC.Generics import qualified Data.HashMap.Strict as HashMap data Person = Person { name :: String, age :: Int } deriving (Generic, Show) instance ToJSON Person main :: IO () main = do let p = Person "random" 100 case toJSON p of Object obj -> print $ HashMap.keys obj -- 对普通记录类型派生的ToJSON实例,下方分支永远不会触发 _ -> print "unexpected JSON type"
运行输出和你原实现一致:["age","name"]
方案2:不需要aeson依赖,直接取Haskell记录字段名
如果你只需要获取记录类型本身定义的字段名,不需要和aeson的序列化逻辑绑定,可以直接用base库自带的Data.Data泛型能力实现,完全不需要引入第三方依赖,性能开销最低:
{-# LANGUAGE DeriveDataTypeable #-} import Data.Data (Data, toConstr, constrFields) data Person = Person { name :: String, age :: Int } deriving (Data, Show) main :: IO () main = print $ constrFields $ toConstr $ Person undefined undefined
运行输出为["name","age"],顺序和你定义记录字段的顺序完全一致,如果需要和aeson输出的排序保持一致,自行做排序处理即可。
内容的提问来源于stack exchange,提问作者vijaicv
相关产品推荐
相关产品推荐

