之前兩篇都是介紹與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("\n");//插入換行符
ret += visit(*this, 0);
return ret;
}
看完代碼才發現, 原來在傳回的字元串裡先插入一個 "\n" 換行符。
我們的故事本來到這裡應該結束了,但總有些強迫症的孩子心裡有點疙瘩,既然都看到這了,幹嘛不再看看 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() << "\n";//如果是上面這幾種類型,那麼直接将其轉換成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 << "\n";
ret << getTabs(depth) << "[\n";
int i = 0;
for (const auto& child : v)
{
ret << getTabs(depth+1) << i << ": " << visit(child, depth + 1);//在這裡讀取Vector中的元素
++i;
}
ret << getTabs(depth) << "]\n";
return ret.str();
}
這函數乍看一下有點莫名其妙,其實我們隻要知道 getTabs(int depth)這個函數是怎麼回事就可以,其他自然迎刃而解。
static std::string getTabs(int depth)
{
std::string tabWidth;
for (int i = 0; i < depth; ++i)
{
tabWidth += "\t";//插入一個制表符
}
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