设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 2589|回复: 9
打印 上一主题 下一主题

[已经解决] VA多了好多":",为什么要用":"

[复制链接]

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2013-8-14
帖子
203
跳转到指定楼层
1
发表于 2014-8-4 20:06:54 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
Scene_Menu
RUBY 代码复制
  1. #--------------------------------------------------------------------------
  2.   # ● 生成指令窗口
  3.   #--------------------------------------------------------------------------
  4.   def create_command_window
  5.     @command_window = Window_MenuCommand.new
  6.     @command_window.set_handler(:item,      method(:command_item))
  7.     @command_window.set_handler(:skill,     method(:command_personal))
  8.     @command_window.set_handler(:equip,     method(:command_personal))
  9.     @command_window.set_handler(:status,    method(:command_personal))
  10.     @command_window.set_handler(:formation, method(:command_formation))
  11.     @command_window.set_handler(:save,      method(:command_save))
  12.     @command_window.set_handler(:game_end,  method(:command_game_end))
  13.     @command_window.set_handler(:cancel,    method(:return_scene))
  14.   end



问题:
冒号有何用啊?
为什么要用?
不能用@吗?(如@command_item)

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2013-8-14
帖子
203
10
 楼主| 发表于 2014-8-5 10:08:46 | 只看该作者
余烬之中 发表于 2014-8-5 08:04
基础
Symbol是一个类(符号类),以冒号打头的都是Symbol的实例(你知道类和实例是什么吧),且都是字面值 ...

感谢
学到了个字面值
也就是 : 更安全、指向性更强兼效率,比起 $ 来讲...

点评

这样啊~感谢啊~  发表于 2014-8-5 10:32
不过全局变量少用是应该的  发表于 2014-8-5 10:21
不能用$代替,最多用字符串代替。作为名字的字符串一般也没啥人会去变他的= =  发表于 2014-8-5 10:21
说安全,因为它的值不变...  发表于 2014-8-5 10:17
如过用$代替: 不就有出错率增大吗 不是method(:@#%#@%)什么的情况  发表于 2014-8-5 10:16
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

百合控

梦石
0
星屑
6643
在线时间
1275 小时
注册时间
2013-8-21
帖子
3657

开拓者

9
发表于 2014-8-5 08:04:53 | 只看该作者
基础
Symbol是一个类(符号类),以冒号打头的都是Symbol的实例(你知道类和实例是什么吧),且都是字面值(你知道字面值是什么吧?)
可以类比引号(注意只能类比),引号括起来的都是String的实例,且都是字面值
比如 "你好" 的值就是它所显示的样子
:ok 的值就是它显示的样子
如果先令 a = :ok
那么a就不是字面值 它显示的是a 但它的值是:ok
method方法和symbol的演示
RUBY 代码复制
  1. class A
  2.   def m(sym)
  3.     return method(sym)
  4.   end
  5. end
  6.  
  7. a = A.new
  8. begin
  9.   a.m(:n) #=> NameError: undefined method 'n' for class 'A'
  10. rescue
  11.   # do nothing
  12. end
  13.  
  14. class A
  15.   def n
  16.     return "你好"
  17.   end
  18. end
  19.  
  20. b = a.m(:n) #=> #<Method: A#n>
  21.  
  22. b.call #=> "你好"

与@的区别
对于符号 只要它存在 它就有值(字面值) 而且这个值不能更改
对于@变量(实例变量) 如果不事先赋值 它就是nil
所以 写法相同的符号 无论写在哪里 代表的都是同一个值
而@变量就不一定了
RUBY 代码复制
  1. class A
  2.   def initialize
  3.     @ok = 1
  4.   end
  5.   def m
  6.     @ok
  7.   end
  8.   def n
  9.     :ok
  10.   end
  11. end
  12.  
  13. class B
  14.   def initialize
  15.     @ok = 2
  16.   end
  17.   def m
  18.     @ok
  19.   end
  20.   def n
  21.     :ok
  22.   end
  23. end
  24.  
  25. A.new.m == B.new.m #=> false
  26. A.new.n == B.new.n #=> true

类变量(@@) 全局变量($)暂且不说了 他们都是可以进行赋值的
回到最初的问题
@command_window.set_handler(:item,      method(:command_item))
@command_window是一个已经赋值了的实例变量 实际上 它的值是一个Window_MenuCommand类的实例 也就是菜单指令窗口
set_handler是定义在Window_MenuCommand中的实例方法 它接受两个参数 一个是符号(aSymbol) 另一个是方法(aMethod)
如果这个菜单指令窗口中某个指令被选中并确认了(每个指令都事先设置了一个符号与之对应 所以上面这个符号实际上是代表某个选项的 我们假设现在选中的指令所对应的符号是:item)
那么 由set_handler所设置的对应的方法就会被调用
这里 我们把:item和method(:command_item)关联了起来
method(:command_item)实际上是一个方法调用
method本身是一个方法 它接受一个参数 可以是符号 可以是字符串 也可以是值为符号/字符串的变量
这个方法会在当前环境中找这个参数所指定的方法 并返回这个方法 上面已经演示过了
大体就是这样

评分

参与人数 1梦石 +1 收起 理由
taroxd + 1 认可答案

查看全部评分

萌新瑟瑟发抖
看到我请叫我去干活
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2013-8-14
帖子
203
8
 楼主| 发表于 2014-8-4 21:37:32 | 只看该作者
本帖最后由 九靈 于 2014-8-4 21:39 编辑

感谢两位前辈
是用symbol来代表方法名吧


刚刚看到的↓
Ruby的符号

Ruby的符号足以让很多初学者迷惑上一段时间,看过本章节后,或许会解开你心中的疑惑。

在Ruby中,一个符号是就是一个Symbol类的实例,它的语法是在通常的变量名前加一个冒号,如
:my_sy

Ruby的符号像一个字符串,因为它内部表现形式是一个字符序列。而与字符串不同的是,每个符号的实例只有一个。看下面的例子:
array = ["foo", "foo", "foo", :foo, :foo, :foo]

建立这个数组后,内存中将有三个内容为"foo"的字符串对象,而只有一个:foo对象。

一个符号有它唯一对应的一个整数值,可以用to_i来获取它。

符号常用的地方是用它来代表变量名或者方法名:
class SomeClass
  attr_accessor :whatever
end

与上面程序对等的程序如下:
class SomeClass
  def whatever
    @whatever
  end
  def whatever=(val)
    @WHATEVER = val
  end
end

你可能会问,为什么不用字符串来表示呢?其实,字符串也是可以的:
attr_reader :alpha
attr_reader "beta"   # 也是合法的

那它们的区别在哪里?某种意义上来说,是为了提高程序性能,节省内存吧。

有的人说,"符号就如同不可变的字符串",从它的行为上来说,可能是对的。但是,Symbol并是是继承至String,而且,与字符串相关
的那些典型操作方法,Symbol也不一定有,也不需要有。


符号不一定看起来是像变量一样,它也可以这样:
sym1 = :"This is a symbol"
sym2 = :"This is, too!"
sym3 = :")(*&^%$"
你可以用这样奇怪的符号来定义实例变量名或方法,你可以使用诸如send或instance_variable_get来获取它们的引用。虽然是可行的,
但请尽量不要使用这么奇怪的符号。


用Symbol作为枚举
==========================================
像Pascal或版本稍晚的C语言,都存在enum这种类型。Ruby不能正真的拥有这样的类型,因为它没有类型检查。但使用Symbol可以用来产生
这样的效果:
North, South, East, West = :north, :south, :east, :west

用Symbol作为元数据
==========================================
通常我们使用捕获异常的方式来处理错误,避免使用老式的返回代码的方式。但是,如果你想用老式的方式,还是可以的。像nil就是这样一个元数据。
我们通常可以这样使用(因为符号是全局的,所以在之后的整个程序中,都可以使用这些符号来作为元数据):
str = get_string
case str
  when String
    # Proceed normally
  when :eof
    # end of file, socket closed, whatever
  when :error
    # I/O or network error
  when :timeout
    # didn't get a reply
end


Symbols, Variables, Methods
==========================================
Symbol最常用的地方就是我们熟知的定义属性了:
class MyClass
  attr_reader :alpha, :beta
  attr_writer :gamma, :delta
  attr_accessor :epsilon
  # ...
end
这里的方法,如attr_accessor,它以传入的符号来确定实例变量的名称,以及读写属性的方法的名称,但这不代表所有的情况
(即总是会自动精确匹配符号和实例变量的名称),例如,当使用instance_variable_set方法的时候,符号和实例变量名必须
精确给出:
sym1 = :@foo
sym2 = :foo
instance_variable_set(sym1,"str")   # 正常,匹配到@foo
instance_variable_set(sym2,"str")   # 错误

不过,记住,在这些地方不一定要使用符号,可以用字符串来替代。


转换Symbol
============================================
Symbol和字符串之间可以互相转换,使用to_s和to_sym来实现:
a = "foobar"
b = :foobar
a == b.to_str    # true
b == a.to_sym    # true   

点评

“一个符号有它唯一对应的一个整数值,可以用to_i来获取它。” 这句话过时了,其他的没什么问题  发表于 2014-8-5 08:00
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

7
发表于 2014-8-4 20:56:03 | 只看该作者
喵呜喵5 发表于 2014-8-4 20:54
这三个是一类:$item、@@item、@item
这三个是一类:"item"、:item、12345

你为什么会产生 ruby 会调用 to_sym 的错觉

RUBY 代码复制
  1. obj = Object.new
  2. class << obj
  3.   def intern
  4.     :method
  5.   end
  6.   alias to_sym intern
  7. end
  8.  
  9. method(obj) # TypeError

点评

因为看到RubyDoc写的是这样method(sym)而不是method(sym/str)所以觉得应该有内部转换【躺【随便翻了翻发现好像也没有找到支持两种不同类型参数的【再次躺  发表于 2014-8-4 21:13
回复 支持 反对

使用道具 举报

Lv5.捕梦者 (暗夜天使)

只有笨蛋才会看到

梦石
1
星屑
21609
在线时间
9412 小时
注册时间
2012-6-19
帖子
7117

开拓者短篇九导演组冠军

6
发表于 2014-8-4 20:54:02 | 只看该作者
九靈 发表于 2014-8-4 20:47
好吧...也许我还没理解"符号类的参数"是什么意思?
$item
@@item

这三个是一类:$item、@@item、@item
这三个是一类:"item"、:item、12345

m = l.method("hello")
实际上是
m = l.method(("hello").to_sym)
("hello").to_sym => :hello
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

5
发表于 2014-8-4 20:51:40 | 只看该作者
九靈 发表于 2014-8-4 20:47
好吧...也许我还没理解"符号类的参数"是什么意思?
$item
@@item

$item: 全局变量
@@item: 类变量
@item: 实例变量
:item : 一个符号

对于符号的理解,就像这样。1是一个整数,"1"是一个字符串,:item是一个符号。
m = l.method("hello") 是正确传入的方式,没有什么容错之说。
只不过我们更倾向于 l.method(:hello)这种方式而已
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
49
在线时间
157 小时
注册时间
2013-8-14
帖子
203
4
 楼主| 发表于 2014-8-4 20:47:19 | 只看该作者
喵呜喵5 发表于 2014-8-4 20:12
method是定义在Object类的方法,至少在Ruby1.92中它只接收符号类的参数,所以用冒号打头传给他一个符号参数 ...

好吧...也许我还没理解"符号类的参数"是什么意思?
$item
@@item
@item
:item
......这些都是吗?
我只知道都是变量...

所以
m = l.method("hello")
"hello" ← 这是所谓的"容错"?
回复 支持 反对

使用道具 举报

Lv3.寻梦者 (版主)

…あたしは天使なんかじゃないわ

梦石
0
星屑
2208
在线时间
4033 小时
注册时间
2010-10-4
帖子
10779

开拓者贵宾

3
发表于 2014-8-4 20:17:04 | 只看该作者
本帖最后由 taroxd 于 2014-8-4 20:19 编辑
喵呜喵5 发表于 2014-8-4 20:12
method(:command_item) 表示 command_item 这个方法…………


冒号表示一个符号,通常用来表示某事物的名字。你用引号 method('command_item') 也是可以的。
符号的好处在于更高的效率,以及看起来更加清晰美观。

method 是一个方法,有关它的介绍参考 F1 文档(更加建议你参考Ruby文档)。这里省略了接收者 self
也就是说,完整的写法是 self.method('command_item')。
该方法可以获得一个 method 对象,该 method 对象的接收者为当前场景(self)。
有关 method 对象的介绍,也请参考 F1(同样更加建议你参考Ruby文档)

点评

Ruby的方法如果是对象就好了……  发表于 2014-8-4 20:24
method和方法原来还有区别的么=口=  发表于 2014-8-4 20:22

评分

参与人数 1梦石 +1 收起 理由
VIPArcher + 1 塞卡行不行?

查看全部评分

回复 支持 反对

使用道具 举报

Lv5.捕梦者 (暗夜天使)

只有笨蛋才会看到

梦石
1
星屑
21609
在线时间
9412 小时
注册时间
2012-6-19
帖子
7117

开拓者短篇九导演组冠军

2
发表于 2014-8-4 20:12:21 | 只看该作者
本帖最后由 喵呜喵5 于 2014-8-4 20:27 编辑

method是定义在Object类的方法,至少在Ruby1.92中它只接收符号类的参数,所以用冒号打头传给他一个符号参数

用@command_item也可以啊,但是用了@command_item以后你在执行这个语句之前还必须令实例变量的值为一个可以转换成符号类的值,多麻烦= =

附上Ruby Doc
http://ruby-doc.org/core-1.9.2/Object.html#method-i-method

method(sym) → method
Looks up the named method as a receiver in obj, returning a Method object (or raising NameError). The Method object acts as a closure in obj’s object instance, so instance variables and the value of self remain available.

class Demo
  def initialize(n)
    @iv = n
  end
  def hello()
    "Hello, @iv = #{@iv}"
  end
end

k = Demo.new(99)
m = k.method(:hello)
m.call   #=> "Hello, @iv = 99"

l = Demo.new('Fred')
m = l.method("hello")
m.call   #=> "Hello, @iv = Fred"

点评

sym只是一个代号,只是一个参数的名称;我没记错的话文档另一处写着“所有表示名字的sym既可以用符号也可以用字符串”  发表于 2014-8-4 20:59
至少RubyDoc里写的method只接受sym啊  发表于 2014-8-4 20:57
字符串哪里类型不对了,本来就是正确的类型  发表于 2014-8-4 20:54
传字符串时自动调用.to_sym而不是甩出一句类型不对不是容错么……  发表于 2014-8-4 20:51
啥容错,字符串本来就可以传入。只能传符号不是太死板了嘛,有的时候需要字符串操作的  发表于 2014-8-4 20:48

评分

参与人数 1梦石 +1 收起 理由
taroxd + 1 认可答案

查看全部评分

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-12 23:21

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表