• Cocos2dx 小技巧(十六)再谈visit(getDescription)


    之前两篇都是介绍与Value相关的,这篇我继续这个话题吧,正好凑个“Value三板斧系列...”。
    在非常久非常久曾经。我用写过一篇博客,关于怎样查看CCArray与CCDictionary里存放的元素:http://blog.csdn.net/star530/article/details/23877429
    如今既然它俩已经都是过去式了,那么之前的查看方法肯定也是不能用了。

    而Value作为它们的替代者之中的一个。自然也有它查看元素的方法。那就是getDescription()这个接口,以下我简单举个样例:

    Value a(10);
    std::string a_str = a.getDescription();
    CCLOG("a = %s",a_str.c_str());//打印出 a 相应的值
    以下看下程序执行结果。输出例如以下信息:


    看输出好像没什么问题。但这里有个疑问。为什么 a = 与 10没有在同一行呢?
    在getDescription()这个接口里。究竟发生了慘绝人寰的事?
    带着疑问与好奇,我们到getDescription()的定义里一探虚实。


    std::string Value::getDescription()
    {
        std::string ret("
    ");//插入换行符
        ret += visit(*this, 0);
        return ret;
    }
    看完代码才发现,原来在返回的字符串里先插入一个 " " 换行符。


    我们的故事本来到这里应该结束了,但总有些强迫症的孩子心里有点疙瘩。既然都看到这了,干嘛不再看看 visit(*this, 0) 这个函数都做了些什么呢?
    好吧,既然你都这样求我了。那...我们继续往下看:

    static std::string visit(const Value& v, int depth)
    {
        std::stringstream ret;//创建一个字符串流
    	
    	//推断Value内元素的类型
        switch (v.getType())
        {
            case Value::Type::NONE:
            case Value::Type::BYTE:
            case Value::Type::INTEGER:
            case Value::Type::FLOAT:
            case Value::Type::DOUBLE:
            case Value::Type::BOOLEAN:
            case Value::Type::STRING:
                ret << v.asString() << "
    ";//假设是上面这几种类型,那么直接将其转换成string型就可以。
                break;
            case Value::Type::VECTOR:
                ret << visitVector(v.asValueVector(), depth);
                break;
            case Value::Type::MAP:
                ret << visitMap(v.asValueMap(), depth);
                break;
            case Value::Type::INT_KEY_MAP:
                ret << visitMap(v.asIntKeyMap(), depth);
                break;
            default:
                CCASSERT(false, "Invalid type!");
                break;
        }
        
        return ret.str();
    }
    上述代码我没有做过多的凝视。我们仅仅要注意两点:
    1、普通的数据类型,如int。string等,能够直接转成string型(asString())后放入ret流中就可以。

    而假设元素类型是Vector或者Map,则须要做进一步的处理;
    2、visit(const Value& v, int depth) 这个函数的第二个參数 depth是个什么玩意?眼尖的我发现进一步处理Vector类型的元素时。调用到visitMap(v.asValueMap(), depth)这个函数。而depth正好是该函数的第二个參数。


    带着疑惑,我们继续:

    static std::string visitVector(const ValueVector& v, int depth)
    {
        std::stringstream ret;
        
        if (depth > 0)
            ret << "
    ";
        
        ret << getTabs(depth) << "[
    ";
        
        int i = 0;
        for (const auto& child : v)
        {
            ret << getTabs(depth+1) << i << ": " << visit(child, depth + 1);//在这里读取Vector中的元素
            ++i;
        }
        
        ret << getTabs(depth) << "]
    ";
        
        return ret.str();
    }
    这函数乍看一下有点莫名其妙。事实上我们仅仅要知道getTabs(int depth)这个函数是怎么回事就能够,其它自然迎刃而解。
    static std::string getTabs(int depth)
    {
        std::string tabWidth;
        
        for (int i = 0; i < depth; ++i)
        {
            tabWidth += "	";//插入一个制表符
        }
        
        return tabWidth;
    }
    原来getTabs()的功能就是插入制表符啊(所谓制表符就是tab键)。而传入的參数depth是多少就加入多少个制表符。
    好了。流程就是这样子。我想非常多人如今脑袋瓜子都还蒙蒙的。没事。以下我举个栗子,然后小伙伴们依据程序的输出结果与上面提到的visit()、visitVector()的代码參照下。


    Value a(10);
    Value b("star is so cool");
    ValueVector star_vec;
    star_vec.push_back(a);
    star_vec.push_back(b);
    //将ValueVector类型转成Value类型才可调用getDescription()
    std::string star_str = ( (Value)star_vec ).getDescription();
    CCLOG("-----------------------");
    CCLOG("%s",star_str.c_str());
    CCLOG("-----------------------");
    程序执行后。输出结果例如以下:


    好了,就酱紫吧。能不能理解就看阁下的悟性了
    尊重原创,转载请注明来源:http://blog.csdn.net/star530/article/details/38071517
  • 相关阅读:
    git/github轻松上传本地项目
    ubuntu下python+flask+mysql完整开发环境配置
    木马另类删除文件的方法
    OpenCV资源
    实现bmp文件到png文件转换
    通过进程ID获得该进程主窗口的句柄
    有趣的Lua表
    让程序在win7下运行时弹出"以管理员身份运行"
    LuaStudio源码分析2资源文件
    LuaCURL
  • 原文地址:https://www.cnblogs.com/llguanli/p/7157088.html
Copyright © 2020-2023  润新知