`
sinkzephyr
  • 浏览: 89649 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

关于s[s.length,1]为什么返回""

    博客分类:
  • Ruby
阅读更多
ROR群(15917997)里有朋友问到一个问题
s="hello"
s[s.length,1]为什么返回"",而不是返回nil或其他

群里展开了讨论,我翻了翻ruby源代码,试着做出解释:
首先查了API,
string[integer, integer]会执行
rb_str_substr(str, NUM2LONG(argv[0]), NUM2LONG(argv[1]));




rb_str_substr是这样的:
VALUE
rb_str_substr(str, beg, len)
    VALUE str;
    long beg, len;
{
    VALUE str2;

    if (len < 0) return Qnil;
    if (beg > RSTRING(str)->len) return Qnil;
    if (beg < 0) {
	beg += RSTRING(str)->len;
	if (beg < 0) return Qnil;
    }
    if (beg + len > RSTRING(str)->len) {
	len = RSTRING(str)->len - beg;
    }
    if (len < 0) {
	len = 0;
    }
    if (len == 0) {
	str2 = rb_str_new5(str,0,0);
    }
    else if (len > sizeof(struct RString)/2 &&
	beg + len == RSTRING(str)->len && !FL_TEST(str, STR_ASSOC)) {
	str2 = rb_str_new4(str);
	str2 = str_new3(rb_obj_class(str2), str2);
	RSTRING(str2)->ptr += RSTRING(str2)->len - len;
	RSTRING(str2)->len = len;
    }
    else {
	str2 = rb_str_new5(str, RSTRING(str)->ptr+beg, len);
    }
    OBJ_INFECT(str2, str);

    return str2;
}


看到这两句
if (len < 0) return Qnil;
if (beg > RSTRING(str)->len) return Qnil;

意思是说要截取的字串长度如果为负数,返回nil
开始的位置超出了原字串的长度,也返回nil

往下看,因为s.lenght刚好等于RSTRING(str)->len,其实会执行到
str2 = rb_str_new5(str, RSTRING(str)->ptr+beg, len);


rb_str_new5是这样的
VALUE
rb_str_new5(obj, ptr, len)
    VALUE obj;
    const char *ptr;
    long len;
{
    return str_new(rb_obj_class(obj), ptr, len);
}


主要是调用了str_new

static VALUE
str_new(klass, ptr, len)
    VALUE klass;
    const char *ptr;
    long len;
{
    VALUE str;

    if (len < 0) {
	rb_raise(rb_eArgError, "negative string size (or size too big)");
    }

    str = str_alloc(klass);
    RSTRING(str)->len = len;
    RSTRING(str)->aux.capa = len;
    RSTRING(str)->ptr = ALLOC_N(char,len+1);
    if (ptr) {
	memcpy(RSTRING(str)->ptr, ptr, len);
    }
    RSTRING(str)->ptr[len] = '\0';
    return str;
}




到了
  if (ptr) {
	memcpy(RSTRING(str)->ptr, ptr, len);
    }




ptr其实已经指向了"hello"的最后一个字符,也就是'\0'了,执行完memcpy后,str成了"",再最后执行
RSTRING(str)->ptr[len] = '\0';

这一句加""加上'\0',是c语言的空字符串.

最后的结果就是""了.

路线是这样的
s[s.length,1]
==> rb_str_substr("hello", 5, 1);
==> rb_str_new5("hello",ptr=5,1);
==> str_new("hello",ptr=5,1)
==>memcpy("hello",ptr=5,1)
==>""
        


分享到:
评论

相关推荐

    java第五次上机题

    `t.length` 返回的是二维数组的长度,即行数,所以`t.length` 等于 2,而 `t[0].length` 返回第一维数组的长度,即每行的元素个数,所以`t[0].length` 等于 3。题目中描述的 `t.length=3` 和 `t[0].length=2` 是错误...

    由串口助手引起的ESP8266出现busy s…问题解决

    因为直接使用的串口助手,8266也设置的回传模式,所以这里可以看到相应的返回,出现了busy s... 那么这个busy对我们的实际操作有没有影响呢,结合我们浏览器显示的内容: 和实际发送的报文: HTTP/1.1 200 OK ...

    数据结构 堆串基本操作代码

    j &lt;= pos + S.length - 2 && k &lt; S.length; j++, k++) T.ch[j] = S.ch[k]; T.length += S.length; } return OK; } ``` ### 三、其他操作 除了上述操作外,还有打印堆串、清空堆串等功能。例如,打印堆串功能...

    kaijiang.rar_MáS

    switch(m.substr(1,1)){ case s : return v.toString() case S : return +v.replace( , \\ )+ case f : return v-0 case d : return v.getFullYear()+ - +v.getMonth()+ - +v.getDate() case D...

    supersized.min

    s=arr[--t],arr[t]=arr[e],arr[e]=s){}h.options.slides=arr}if(h.options.slides.length&gt;1){if(h.options.slides.length&gt;2){vars.current_slide-1&lt;0?loadPrev=h.options.slides.length-1:loadPrev=vars.current_...

    顺序表的基本操作的实现

    if (i &lt; 1 || i &gt; S.length() + 1) { cout !" ; exit(0); } for (int j = S.length(); j &gt;= i; j--) { S.data[j] = S.data[j - 1]; } S.data[i - 1] = x; S.len++; return 0; } ``` 3. 删除所有具有给定...

    hls.min.js

    default:s=Array.prototype.slice.call(arguments,1),r.apply(this,s)}else if(n(r))for(s=Array.prototype.slice.call(arguments,1),u=r.slice(),a=u.length,l=0;l;l++)u[l].apply(this,s);return!0},r.prototype....

    MyEclipse注册机源码

    if (s == null || s.length() == 0) return s; byte abyte0[] = s.getBytes(); char ac[] = new char[s.length()]; int i = 0; for (int k = abyte0.length; i ; i++) { int j = abyte0[i];

    八种排序方法附实现源码.zip

    //s.quickSort(arr, 0, arr.length-1); //快速排序 //int[] temp = new int[arr.length]; //s.mergeSort(arr, 0, arr.length-1, temp); //归并排序 //s.headSort(arr);//堆排序 System.out.println(Arrays....

    javascript-leetcode面试题解动态规划问题之第139题单词拆分-题解.zip

    遍历字符串`s`的每个字符,更新`dp`数组,并在最后检查`dp[s.length]`是否为`true`,如果是,则返回`true`,否则返回`false`。 ### 5. JavaScript实现 ```javascript function wordBreak(s, wordDict) { const dp...

    使用KMP实现文本的查找与替换

    while (i &lt; S.length && j &lt; T.length) { if (S.str[i] == T.str[j]) { i++; j++; } else if (j == 0) { i++; } else { j = next[j]; } } if (j == T.length) v = i - T.length; else v = -1; return v...

    Seat Geek 著名的python FuzzyWuzzy算法的 C# .NET 模糊字符串匹配实现

    int[,] dp = new int[s.Length + 1, t.Length + 1]; for (int i = 0; i &lt;= s.Length; i++) dp[i, 0] = i; for (int j = 0; j &lt;= t.Length; j++) dp[0, j] = j; for (int i = 1; i &lt;= s.Length; i++) { for ...

    数据结构课程设计(翻译标准C版本)

    printf("%d\n",*(S.top-1)); } } void Push () { scanf("%d",S.top); *S.top++; S.Length++; printf("OK\n"); } void Pop () { if(S.top==S.base) { printf("NULL\n"); } else { S.Length--;...

    如何确定货币形式(c#)

    s.LastIndexOf('.') == s.Length - 1 || n.Length - n.LastIndexOf('.') &gt; 3 || (s.IndexOf('0') == 0 && s.IndexOf('.') &gt; 1)) { return false; } // 检查千位分隔符的位置和数量 int i = 1; for (i = 1...

    JavaScript自定义函数实现查找两个字符串最长公共子串的方法

    本文实例讲述了... var S=sstr= ,L1=s1.length,L2=s2.length; if (L1&gt;L2){ var s3=s1;s1=s2,s2=s3,L1=s2.length;} for ( var j=L1;j&gt; 0 ;j--) for ( var i= 0 ;i&lt;=L1-j;i++){ sstr = s1.substr(i,j); if

    文本文件单词的检索和计数课程设计汇本实验报告.doc

    fwrite(&S, S.length, 1, fp); fprintf(fp,"%c", 10); //是输入换行 printf("结束输入吗?y or n: "); yn=getchar(); } fclose(fp); //关闭文件 printf("建立文件结束!"); } void SubStrCount(){ FILE *fp...

    JAVA——linux

    String s = Integer.toString(i+1);// "1" char[] num = s.toCharArray(); // {'1'} System.arraycopy(num, 0, ch, ch.length-num.length, num.length); String ball = new String(ch); red[i] = ball; } ...

    DOS下用的GHOST 11.0.2.1573 版本(很好用的哦)

    Time elapsed.......1:01 Time remaining.....8:57 Program Call Stack AbortLog Generic_Abort ReadDiskSectorsNoOverlayTranslation ReadDiskSectors FatReadPartSectors ReadFATsector GetFATsectorOut ...

    经常用到的javascript验证函数收集.docx

    if (whitespace.indexOf(s.charAt(s.length - 1)) != -1) { var i = s.length - 1; while (i &gt;= 0 && whitespace.indexOf(s.charAt(i)) != -1) { i--; } s = s.substring(0, i + 1); } return s; } ``` 4. ...

    md5.js-javaScript

    export function md5_hex(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));} export function md5_b64(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));} export function md5_str(s)...

Global site tag (gtag.js) - Google Analytics