多数程序语言的学习第一步常为了解资料型态,毕竟分不清楚资料的型态的话,就不可能对资料做出正确处理或判断,以比喻来说,买股票时,明知道电子股会涨,但是却买进保护伞公司的股票,以为保护伞公司是电子科技股,结果是搞生化的!?
多数文章资料都会直接说一句Ruby里几乎所有东西都为物件
,造成这点的原因是,Ruby在设计上已经将资料的特性与方法包装後,组成各种class,所谓的东西
都是指class产生的实体。
BasicObject
为所有常用类别的顶端(但Class
的顶端是Module
),再以duck typing
设计风格,将资料特性分组好,给予我们想要执行的方法包装好後,再给予一个名字(标签,常数),就成了许多的新class。
物件即为class的实体化,所以物件本身就包含了特性与方法,所以才可以操作物件,因此Ruby内所有东西都为物件
。
不是所有物件导向设计的程序语言都是如此设计,但Ruby这样设计,且物件导向的很彻底。
wiki--物件导向程序设计
文章尽量导向中文资料,能力许可下还是看英文资料较好。
Ruby中有个语法,在资料後面加上.class
,可以查资料的类别。
2.7.3 :020 > :a1234.class
=> Symbol
2.7.3 :021 > 1234.class
=> Integer
2.7.3 :022 > "1234".class
=> String #有""或''的就为字串。
2.7.3 :023 > [1, 2, 3, 4].class
=> Array
2.7.3 :024 > (1..4).class
=> Range
2.7.3 :025 > {:a => 1, "b" => 2, c: 3}.class
=> Hash
另外可以用.methods
对类别产生的实体查询本身有哪些方法。(方法等於怎麽操作这些资料)
2.7.3 :022 > new_array = Array.new
=> []
2.7.3 :023 > new_array.methods
=> [:to_h, :include?, :&, :*, :+, :-, :at, :fetch, :last, :union, :difference, :intersection, :push, :append, :pop, :shift, :unshift, :each_index, :join, :rotate, :rotate!, :sort!, :sort_by!, :collect!, :map!, :select!, :filter!, :keep_if, :values_at, :delete_at,
略....]
#太多了
2.7.3 :024 > new_array.methods.size
=> 192
#192种.
2.7.3 :067 > Array.methods.size
=> 114
#补充:Array原生只有114种方法,new出来的有多78种。可以两者相减看看多哪些方法
Array.methods - new_array.methods
较特殊的。
2.7.3 :024 > true.class
=> TrueClass
2.7.3 :025 > false.class
=> FalseClass
2.7.3 :026 > nil.class
=> NilClass #null或其他语言可能拼法不同。
布林值
,Ruby没有这种型别,但是有给予类别,在我个人学习後会比较让自己去记得Ruby只有类别,没有型别。
但是资料的确是都有自己的型态没错。(记忆体储存方式)
nil
就是空的,会去记,Ruby为了让你看到空白,所以让你看到nil
2.7.3 :003 > nil.to_s
=> ""
#真的如果有新手路过看到这个还看不懂,请先略过之後都会说明。
当然Ruby中不只这六种类别,这六种为比较常见的Ruby资料类别而已,初学会以这几种出发。除了符号这类别可能比较陌生,还有Hash在Ruby叫杂凑外,其他的资料处理方式都与其他程序大同小异。认识资料类别最大目的为,怎麽处理资料,Ruby虽然为强型别语言,但个类别间有很多方法做转换,甚至有很多同名方法,初学以能越快速掌握越好。而由於网路上大神们的资料已经够详细,我将会直接以解题做分享。
Ruby是物件导向程序设计的语言。
无论了不了解OOP,先知道如果需要处理物件,以变数来指向,会比较便利。
变数与常数简单一点来想就是,只是一个标签(名字),拿来指向一个物件,物件於Ruby多指类别的实例,也就是实体,最简单的实体就是基础的资料,指向完成後,变数成为了实体(物件)的名字,我们可以将变数拿来操作,不用重复输入物件(实体)。
例如:x = 123
看起来像x这个变数等於123
事实上x这变数指向123
=
是个指向方法,不是等於。
例如:
2.7.3 :091 > num = 202120212021
=> 202120212021
2.7.3 :092 > num / 2021
=> 100010001
2.7.3 :093 > num * 2021
=> 408484948494441
2.7.3 :094 > num - 2021
=> 202120210000
以及以後会常看到的
2.7.3 :099 > num = 10
=> 10
2.7.3 :100 > num
=> 10
2.7.3 :101 > num = num - 5
=> 5
2.7.3 :102 > num
=> 5
2.7.3 :103 > num = num * 5
=> 25
2.7.3 :104 > num
=> 25
#赋予运算,下面会稍微提到为何可以如此操作。
变数为开头小写英文的数字加组合,如abc
、a123
、a1b1
、aAaa
,除了_
不要有计算符号於内,如a+c
、a@a
、x123^
这些都会造成错误。
常数为开头大写英文的数字加组合,其余与变数相同,如Abc
、A_BC
。
因此於Ruby,除开头大小写外,使用Ruby者多以常数指向不轻易变动之资料,若要变动则会有警告提示(而已),所以类别与模组强制使用常数来命名。
2.7.3 :005 > num = 1
=> 1
2.7.3 :006 > num = 2
=> 2
2.7.3 :007 > num = 3
=> 3
2.7.3 :008 > Num = 1
=> 1
2.7.3 :009 > Num = 2
(irb):9: warning: already initialized constant Num
(irb):8: warning: previous definition of Num was here
=> 2
#对,就警告而已,我们是大人了,不要做被警告的事就好。
2.7.3 :012 > def Add(num1, num2)
2.7.3 :013 > num1 + num2
2.7.3 :014 > end
=> :Add #方法用变数,这是错误示范,强调Ruby的风格较自由,但Ruby使用者不会这麽做。
2.7.3 :015 > class error
2.7.3 :016 > p "错误"
2.7.3 :017 > end
SyntaxError ((irb):15: class/module name must be CONSTANT)
class error
^~~~~ #没有例外
#类别只能用常数。
保持可阅读性,宁可越详细越好,也尽量不要有x
、a
、xy
、这种无意义的魔法编码。
请让一年後的自己还知道自己了写什麽
使用者多以蛇式命名、first_number
。
保留变数:很多,记会喷错就代表不能用,例如不可能会有nil = 123
,if = 123
。
会於进入Rails前说明。
我们先了解怎麽用。
什麽是符号?
符号指:
加上变数
。变数前面挂上:
就会成为符号。
2.7.3 :019 > :abc
=> :abc
2.7.3 :010 > :acb.class
=> Symbol
#不是:是符号,而是:abc是一个符号。
#不是指+,-,*,%这些已经被包装成方法的运算式,也不是指@, #, $这些。
符号常见於Hash中当做Key指向Value,{:a => 1}
,或将方法名称标记,等於是一个固定住的物件。
2.7.3 :001 > def some_method
2.7.3 :002 > p "do something"
2.7.3 :003 > end
=> :some_method
# 运用到Rails上会看到下面类似使用方式。
after_save :some_method
# 在实体存挡後执行一个方法。
#我们可以随意将变数随意拿来使用
2.7.3 :004 > some_method = 123
=> 123
2.7.3 :005 > some_method = 1234
=> 1234
#但符号不能
2.7.3 :006 > :some_method = 123
SyntaxError ((irb):6: syntax error, unexpected '=', expecting end-of-input)
:some_method = 123
^
#即使变数一直改指定,刚刚def的方法不会受影响。
2.7.3 :007 > some_method()
"do_something"
=> "do_something"
some_method这串英文只是变数,可以指向任何资料,也可以当方法的名称。
:some_method等於是有个方法(物件)出现了,给他除了变数外,加固给他一个特别的名字。
Hash中,字串也可以当Key。
2.7.3 :025 > {:a => 1, "b" => 2, c: 3}.class
=> Hash
#上面写法错误示范,下篇介绍Hash会说明。
但符号的记忆体位置是固定的,字串不是。
2.7.3 :014 > :some_method.object_id
=> 2041948
2.7.3 :015 > :some_method.object_id
=> 2041948
2.7.3 :016 > "some_method".object_id
=> 180
2.7.3 :017 > "some_method".object_id
=> 200
2.7.3 :018 > "some_method".object_id
=> 220
2.7.3 :019 > "some_method".object_id
#也所以Rails还是常见。
after_save :some_method
#下面也是可以。
after_save "some_method"
符号,字串,变数三者是不同的。
符号,字串为类别的一种,:symbol
与"string"
则已经是实体(物件),变数只是指向物件(实体)的标签。
符号,字串都可以当KEY指向物件,而由於记忆体固定,处理符号会比处理字串稍快,但字串本身具有方法就多,选用上可视状况更改。
num = num + 1
符号与字串就不能这样操作,在指向(=)这个方法前面只能是变数。
那 = 这方法是前面先执行还是後面先执行?
2.7.3 :002 > x.class
NameError (undefined local variable or method `x' for main:Object)
#x是变数,不是任何类别
2.7.3 :003 > x = z
NameError (undefined local variable or method `z' for main:Object)
#z是变数,但没指向任何物件。
2.7.3 :004 > x.class
=> NilClass
#但是刚刚的x已经变成一种nil类别的。但还是没有意义喔nil於Ruby就是nil。
2.7.3 :005 > z.class
NameError (undefined local variable or method `z' for main:Object)
#z却没有
我会先回答,= 将前面变数预设成nilcalss,= 後面是运算式(或方法或物件)的回传值。
答非所问!?
2.7.3 :019 > 1.class
=> Integer
2.7.3 :020 > 0101.class
=> Integer #2进制
2.7.3 :030 > "32".to_i.class #=> 32
=> Integer
2.7.3 :025 > x = 50
=> 50
2.7.3 :026 > x.class
=> Integer #变数指向什麽资料,变数则表示什麽类别。
2.7.3 :027 > arr = [1, 2, 4, 5]
=> [1, 2, 4, 5]
2.7.3 :028 > y = arr.size
=> 4
2.7.3 :029 > y.class
=> Integer
2.7.3 :031 > (x - y).class
=> Integer #运算式,方法结果为数字,类别则为数字。
处理数字类别时,理所当然的对数学越了解越吃香,但数学不强,至少要认识基本运算符号到底求的是什麽。
2 * 3 #=>6 ,一个*是乘法
2 ** 3 #=>8 ,两个**是次方
10 / 2 #=>5 ,/ 是求商
10 % 2 #=>0 ,% 是求余
#赋予运算 +=, /=, *=等
#判断 ==, !=, <, >等。
2.7.3 :032 > 1.0.class
=> Float
2.7.3 :033 > 1.0342342343.class
=> Float
2.7.3 :034 > y = 7 / 3
=> 2
2.7.3 :035 > y.class
=> Integer
2.7.3 :036 > y = 7 / 3.0
=> 2.3333333333333335
2.7.3 :037 > y.class
=> Float
初期最重要一点,Integer与Float运算结果为Float。
这三题刚好都可以用单纯数学来解,所以一起说了避免我之後偷懒拿来混天数。
另外预防针:由於菜鸟,时间空间复杂度我不会去讨论,能解优先。
题目连结Power of Two:https://leetcode.com/problems/power-of-two/
题目连结Power of Three:https://leetcode.com/problems/power-of-three/
题目连结:Power of Four:https://leetcode.com/problems/power-of-four/
三题分别求Input是否为2, 3, 4的次方数。
三题都可以跑回圈
#0次方都是等於1,所以1一定对。
return true if n == 1
#设定自乘次数起始值
power_number = 1 #设1是因为0次方是1
#Input都一定是2或3或4,自己乘自己N次後会变成的数。请记得我们在三题一起解..
while power_number < n
power_number *= 2 #或3 , 4
end
power_number == n
整理一下
def is_power_of_?(n) # ? = two, three, four
return true if n == 1
power_number = 1 #设1是因为0次方是1
while power_number < n
power_number *= ? #?请自行换2,3,4
end
power_number == n
end
而数学比较好的人,可能会了解,2或3的(n次方数大的)除以2或3的(n次方数小的),一定没有余数这件事。
2.7.3 :036 > (2**100)%(2**50)
=> 0
2.7.3 :037 > (2**100)%(2**99)
=> 0
2.7.3 :038 > (2**100)%(2**4)
=> 0
2.7.3 :039 > (2**100)%(2**0)
=> 0
所以可以更快的想到另一种解答。
#2的,为何用2的32次方,因为题目提示有说 n < 2**32
n <= 0 ? false : (2**32 % n == 0)
#3的,1162261467是3的19次方,20次方就超过 2**32了
n > 0 && 1162261467 % n == 0
2用三元运算子写,3用两个判断句合并,写法不同目的相同。
另外,4的确也符合(大的N次方)%(小的N次方)是余零这件事,但是由於4 = 2*2这件事,所以不会直接拿来解,但可以利用
(4**n - 1) % 3 == 0
这个逻辑来解喔。
本日结束,明日会用其他例题说明字串,范围,阵列,杂凑。
整理今天提到。
1.变数与常数差异。
2.符号、变数、字串三者差异。
3.资料基本型态:Integer
4.leetcode:power_of_two..four
>>: Day 01:Hello Computer Science!
今天延续之前的主题,我们将使用EfficientNetB0的架构,但不使用预训练权重,参考了Kera...
前言: 前面我们介绍了很多html, css, php和mysql相关的内容了!今天我们要继续来介...
Hello, 各位 iT邦帮忙 的粉丝们大家好~~~ 本篇是 Re: 从零开始用 Xamarin 技...
今天要来说到显示讯息,从我们使用电脑的过程中,很常会遇到跳出对话框让我们选择是或否或取消,或是当我们...
今天我们要示范如何用Parrot Security的nmap来执行NFS Enumeration(列...