代码之家  ›  专栏  ›  技术社区  ›  Felix Ogg

Ruby将字符串隐式转换为整数(typeError)

  •  0
  • Felix Ogg  · 技术社区  · 7 年前

    我尝试使用一个YAML文件,从中读取并向其中写入一个值列表。在这个脚本的第一次运行中,yaml文件被正确创建,但是在第二次运行时,它抛出了一个转换类型错误,我不知道该如何修复。

    db_yml = 'store.yml'
    
    require 'psych'
    begin
        if File.exist?(db_yml)
            yml = Psych.load_file(db_yml)
            puts "done load"        
    
            yml['reminders']['reminder_a'] = [123,456] 
            yml['reminders']['reminder_b'] = [457,635,123]
            File.write(db_yml, Psych.dump(yml) ) 
        else 
          #the file does not exist yet, create an empty one.
            File.write(db_yml, Psych.dump(
            {'reminders' => [
                {'reminder_a'=> [nil]}, 
                {'reminder_b'=> [nil]}
            ]}
      )) #Store
        end
    rescue IOError => msg  
      # display the system generated error message  
      puts msg 
    end
    

    生成文件商店.yml首次运行时:

    ---
    reminders:
    - reminder_a:
      - 
    - reminder_b:
      - 
    

    到现在为止,一直都还不错。但在第二次运行中,它失败了

    done load
    yamlstore.rb:23:in `[]=': no implicit conversion of String into Integer (TypeError)
            from yamlstore.rb:23:in `<main>'
    

    你能告诉我哪里出了问题吗?

    2 回复  |  直到 7 年前
        1
  •  4
  •   3limin4t0r    6 年前

    YAML文件没有问题。但是,创建文件时,请使用以下结构创建它:

    yaml = {
      'reminders' => [
        {'reminder_a'=> [nil]}, 
        {'reminder_b'=> [nil]}
      ]
    }
    

    请注意 yaml['reminders'] 是一个数组。哪里出了问题:

    reminders = yaml['reminders']
    reminder_a = reminders['reminder_a'] # <= error
    
    # in the question example:
    # yml['reminders']['reminder_a'] = [123,456]
    

    reminders 是一个数组,不能通过传递字符串作为索引来访问它。您有两种选择:

    1. 在我看来,最好的选择(如果您想通过键访问提醒)是将结构更改为使用哈希而不是数组:

      yaml = {
        'reminders' => {
          'reminder_a'=> [nil], 
          'reminder_b'=> [nil]
        }
      }
      

      使用上述结构,您可以通过以下方式访问提醒:

      yaml['reminders']['reminder_a']
      
    2. yaml['reminders'].each do |reminder|
        reminder['reminder_a'] = [123,456] if reminder.key? 'reminder_a'
        reminder['reminder_b'] = [457,635,123] if reminder.key? 'reminder_b'
      end
      
        2
  •  6
  •   Jörg W Mittag    7 年前

    错误消息说您传递了一个 String Integer . Ruby希望某个东西可以隐式转换为 整数 Array . 因此,每当您看到此错误消息时,您可以99%确定您正在索引 数组 带着你认为是 整数 但是不是,或者你正在索引一个 数组 你认为是另一回事(很可能是 Hash ). (另一种可能性是,你正在尝试用混合的 Integers Strings .)

    您要创建的文件类型如下所示:

    Map<String, Sequence<Map<String, Sequence<Int | null>>>>
    

    但是,您正在访问它,就好像它是这样键入的:

    Map<String, Map<String, Sequence<Int | null>>>
    

    更具体地说,您正在创建与键对应的值 'reminders' 作为一个 序列 (在YAML术语中 ( 搞砸 数组 整数 .

    但是,您正在使用 字符串 ,好像是一个 搞砸

    因此,您需要更改访问值的方式,如下所示:

    yml['reminders'][0]['reminder_a'] = [123, 456]
    #               ↑↑↑
    
    yml['reminders'][1]['reminder_b'] = [457,635,123]
    #               ↑↑↑
    

    File.write(db_yml, Psych.dump(
    { 'reminders' => {
    #                ↑
        'reminder_a' => [nil],
    #  ↑                     ↑
        'reminder_b' => [nil]
    #  ↑                     ↑
    }
    

    因此,生成的YAML文档如下所示:

    ---
    reminders:
      reminder_a:
        - 
      reminder_b:
        - 
    
    推荐文章