Project1

标题: 关于代码中传默认参数的问题 [打印本页]

作者: 掘窖人    时间: 2023-3-12 17:14
标题: 关于代码中传默认参数的问题
本帖最后由 掘窖人 于 2023-3-12 17:27 编辑

比如代码中传参如果
def nnt (a=1,b=2,c)
  @at=a
  @bt=b
  @ct=c
end

我调用方法的时候写成:$game_player.nnt (5),那它会知道我想把 5 传给 变量c 。

我想问,如果所有参数都填了默认参数,但我只是想给biao1传递参数,那该怎么写?(前提是这个biao1还是填了默认参数的情况下。)
                                                                                ↓

def biao_shi(dir = $game_player.direction,biao = 1,biao1=5)
     if $game_player.direction==dir
        if Input.trigger?(:C)
          if $game_variables[72]==biao
                 $game_variables[73]=biao1
                 $game_temp.reserve_common_event(21)
    end
       end
          end
end
作者: soulsaga    时间: 2023-3-12 21:52
如果所有参数都填了默认参数,但我只是想给biao1传递参数

测试过如果所有参数都填了默认参数传一个參数默认是给第一个传值
也就是你说的$game_player.nnt (5)
结果是给第一个參数传值
作者: 掘窖人    时间: 2023-3-12 21:57
soulsaga 发表于 2023-3-12 21:52
如果所有参数都填了默认参数,但我只是想给biao1传递参数

测试过如果所有参数都填了默认参数传一个參数默 ...

它如果是全部都是默认参数,想要给后面的参数传参,就要给前面的所有参数都传一次参。好麻烦,我只是想传给后面某一个参数传参而已。
作者: 喵呜喵5    时间: 2023-3-13 13:05
本帖最后由 喵呜喵5 于 2023-3-13 13:45 编辑
  1. def hello(params={})
  2.   params = {
  3.     x: 12,
  4.     y: 13,
  5.     z: 14
  6.   }.merge(params)
  7.   msgbox(params[:x], "-", params[:y], "-", params[:z])
  8. end

  9. hello
  10. hello(x: 233)
  11. hello(x: 456, z: 789)
  12. hello(y: 'hello')
复制代码


具名参数印象中有看过更优雅的写法,但我忘了哎嘿(Ruby 2.0 的话倒是有具名参数,但 RMVA 用的是 Ruby 1.9)
作者: 掘窖人    时间: 2023-3-14 01:53
本帖最后由 掘窖人 于 2023-3-14 01:59 编辑
喵呜喵5 发表于 2023-3-13 13:05
具名参数印象中有看过更优雅的写法,但我忘了哎嘿(Ruby 2.0 的话倒是有具名参数,但 RMVA 用的是 Ruby 1 ...

def kk2(a={})
   a={:x=>14,:y=>15,:z=>16}.merge(a)                                
   b=a[:x]+1
   p b
  
end  

kk2(:x=>232)
kk2(:x=>665)

虽然会用了,但是有个地方不理解,a={:x=>14,:y=>15,:z=>16}.merge(a) 这个地方,

我写成:


a={:x=>14,:y=>15,:z=>16}
a.merge(a)

得出不一样的东西,这里思路是怎样的弄不明白,方法不是跟a调用一样吗?
作者: soulsaga    时间: 2023-3-14 08:17
掘窖人 发表于 2023-3-14 01:53
def kk2(a={})
   a={:x=>14,:y=>15,:z=>16}.merge(a)                                
   b=a[:x]+1


merge是合井两个哈希返回新的哈希
所以应该要写成?
def kk2(a={})
b={:x=>14,:y=>15,:z=>16}
b.merge(a)
这样返回的是新传入的參数

其实我还没测试过..如果有误导成份请见谅
作者: 喵呜喵5    时间: 2023-3-14 12:45
本帖最后由 喵呜喵5 于 2023-3-14 13:38 编辑

merge 这一步是在做参数的合并

  1. { 参数1: 1, 参数2: 2, 参数3: 3 }.merge({ 参数3: 4 }) # => { 参数1: 1, 参数2: 2, 参数3: 4 }
复制代码


在这个流程里就是把你要自定义参数和默认的参数合并到一起,作为一个最终的参数

所以你这里的代码是有问题的,你覆盖了默认参数,然后就默认参数自己和自己合并了

  1. a={:x=>14,:y=>15,:z=>16} # 这一行,你把传入的参数a直接用默认参数覆盖了
  2. a.merge(a) # 这一行,你自己在与自己合并,因此合并后的值没有变化
复制代码


原始的代码里其实还涉及一个点就是运算符优先级的问题

  1. params = { x: 15 }
  2. params = { x: 12, y: 13, z: 14 }.merge(params)
复制代码


merge 的优先级高于赋值的优先级,因此实际执行的时候其实是先将 params 当前值作为 merge 的参数,最后再将 merge 的结果重新赋值给 params 作为最新值


@soulsaga 6楼的回复其实也有问题

merge 的作用是返回一个合并后的新哈希,因此,实际上应该这么去用

  1. a={:x=>4}
  2. b={:x=>1,:y=>2,:z=>3}
  3. c=b.merge(a)
  4. p a,b,c
复制代码


如果不想用赋值的话可以用 merge! ,它的作用是合并已有的哈希

  1. a={:x=>4}
  2. b={:x=>1,:y=>2,:z=>3}
  3. b.merge!(a)
  4. p a,b
复制代码

作者: kuyenda    时间: 2023-3-14 16:06
按位置给定的参数叫位置参数,如果你只想给某个位置参数传参是不行的,要么把按需传递的部分都放到末尾的散列参数,然后用散列变量和键去访问。要么用关键词参数(旧版本可能不支持)
  1. irb(main):005:1* def foo a=1, b=2
  2. irb(main):006:1*   puts b
  3. irb(main):007:0> end
  4. => :foo
  5. irb(main):010:0> foo b=3
  6. 2
复制代码

  1. irb(main):022:1* def foo opt={}
  2. irb(main):023:1*   puts opt[:a]
  3. irb(main):024:0> end
  4. 028:0> foo({:a=>1})
  5. 1
复制代码

调用的时候文字散列可以省略{}




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1