Ruby 使用了 Symbols 和 Hash 来达到虚拟关键字参数(Pseudo-Keyword Arguments)。这种技巧被广泛应用在 Ruby 的函式库和 Rails 中,增加了阅读性,也很容易使用。
def blah(options)
puts options[:foo]
puts options[:bar]
end
blah(:foo =>"test", :bar =>"test")
Ruby 也可以将参数列当成阵列使用:
def sum(*args)
puts args[0]
puts args[1]
puts args[2]
puts args[3]
end
sum(1,2,3)
如此就可以设计出不固定参数列、十分弹性的 API。类似於 C++ 的 function overloading。在 Rails 中也十分常见这样的 API 设计,例如 link_to 就支援了两种用法:
# USAGE-1 without block
<% link_to 'Posts list', posts_path, :class =>'posts' %>
# USAGE-2 with block
<% link_to posts_path, :class =>'posts' do %>
Posts list
<% end %>
搭配虚拟关键字参数使用的话,可以参考 ActiveSupport#extract_options! 这个小技巧取出 Hash 值。
2. Code Blocks
程式区块(Block)是 Ruby 最重要的特色,除了拿来做迭代(Iteration)之外,也可以包装前後置处理(pre- and Post-processing),一个最基本的例子就是开档了,一般程序式的写法如下:
f = File.open("myfile.txt", 'w')
f.write("Lorem ipsum dolor sit amet")
f.write("Lorem ipsum dolor sit amet")
f.close
使用 Block 之後,我们可以将 f.close 包装起来,不需要明确呼叫。只要程式区块结束,Ruby 就会自动关档。程式一来因为缩排变得有结构,二来也确定档案一定会关闭(不然就语法错误了)
# using block
File.open("myfile.txt", 'w') do |f|
f.write("Lorem ipsum dolor sit amet")
f.write("Lorem ipsum dolor sit amet")
end
另一个程式区块的技法,是用来当做回呼(Dynamic Callbacks)。在 Ruby 中,程式区块也是物件,於是我们可以将程式区块如透过”注册”的方式先储存下来,之後再依照需求找出来执行。例如在 Sinatra 程式中:
get '/posts' do
#.. show something ..
end
post '/posts' do
#.. create something ..
end
我们”注册”了两个回呼:一是当浏览器送出 GET ‘/posts’ 时,会执行 show something 的程式区块,二是 POST ‘/posts’ 时。
3. Module
模组(Module)是 Ruby 用来解决多重继承问题的设计。其中有一招 Dual interface 值得一提:
module Logger
extend self
def log(message)
$stdout.puts "#{message} at #{Time.now}"
end
end
Logger.log("test") # as Logger’s class method
class MyClass
include Logger
end
MyClass.new.log("test") # as MyClass’s instance method
Ruby 的 extend 作用是将模组混入(mix-in)进单件类别(singleton class),於是 log 这个方法除了可以像一般的模组被混入 MyClass 中使用,也可以直接用 Logger.log 呼叫。
要将 Ruby 模组的混入成类别方法(class method),也有一些常见的 pattern 模式,可以将模组设计可以同时混入实例方法(instance method)和类别方法,请参阅投影片范例。这在撰写 Rails plugin 时非常常用。
4. method_missing?
Ruby 的 Missing 方法是当你呼叫一个不存在的方法时,Ruby 仍然有办法处理。它会改呼叫 method_missing 这个方法,并把这个不存在的方法名称传进去当做参数。这个技巧在 Rails 的 ActiveRecord 中拿来使用:
class Person <ActiveRecord::Base
end
p1 = Person.find_by_name("ihower")
p2 = Person.find_by_name_and_email("ihower", "[email protected]")
其中 find_by_name 和 find_by_email 就是这样的方法。不过这个技巧不是万能丹,它的执行效率并不好,所以只适合用在你没办法预先知道方法名称的情况下。不过也不是没有补救之道,如果同样的方法还会继续呼叫到,你可以在 method_missing 之中用 define_method 或 class_eval 动态定义此方法,那麼下次呼叫就不会进来 method_missing,进而获得效能的改善。事实上,ActiveRecord::Base 的 method_missing 就是这麼做的。(感谢 BigCat 留言提醒我有此补救之道)
另一个 Missing 方法的绝妙 API 设计,是拿来构建 XML 文件:
builder = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>2)
builder.person do |b|
b.name("Jim")
b.phone("555-1234")
b.address("Taipei, Taiwan")
end
# <person>
# <name>Jim</name>
# <phone>555-1234</phone>
# <address>Taipei, Taiwan</address>
# </person>
搭配了区块功能,就能用 Ruby 语法来写 XML,非常厉害。
5. const_missing
除了 method_missing,Ruby 也有 const_missing。顾名思义就是找不到此常数时,会呼叫一个叫做 const_missing 的方法。现实中的例子有 Rails 的 ActiveSupport::Dependencies,它帮助我们不需要先载入所有类别档案,而是当 Rails 碰到一个还不认识的常数时,它会自动根据惯例,找到该档案载入。
我们也可以利用这个技巧,针对特定的常数规则来处理。例如以下的程式会自动将 U 开头的常数,自动转译成 Unicode 码:
class Module
original_c_m = instance_method(:const_missing)
define_method(:const_missing) do |name|
if name.to_s =~ /^U([0-9a-fA-F]{4})$/
[$1.to_i(16)].pack("U*")
else
original_c_m.bind(self).call(name)
end
end
end
puts U0123 # ģ
puts U9999 # 香
6. Methods chaining
方法串接是一个很常见的 API 设计,透过将方法的回传值设成 self,我们就可以串接起来。例如:
[1,1,2,3,3,4,5].uniq!.reject!{ |i| i%2 == 0 }.reverse
# 5,3,1
7. Core extension
Ruby 的类别是开放的,可以随时打开它新增一点程式或是修改。即使是核心类别如 Fixnum 或是 Object(这是所有类别的父类别) 都一样。例如 Rails 就定义了一些时间方法在 Fixnum 里:
class Fixnum
def hours
self * 3600 # 一小时有多少秒
end
alias hour hours
end
Time.now + 14.hours
Ruby 的物件模型与元编程(Meta-programming)
在 Ruby 中,所有东西都是物件。甚至包括类别(class)本身也是物件。这个类别物件(class object)是一个叫做 Class 的类别所实例出来的物件。而所有的物件(当然也包括类别物件),都有一个 metaclass (又叫做 singleton, eigenclass, ghost class, virtual class 等名字)。定义在 metaclass 里的方法,只有该物件能够使用,也就是 singleton method (单件方法),只有该物件才有的方法。
了解什麼是 metaclass 是 Ruby 元编程的一个重要前提知识。Ruby 元编程最常用的用途,就是因应需求可以动态地定义方法,例如在 Rails ActiveRecord 中常见的 Class Macro 应用。
要能随心所欲动态定义方法的关键重点,就是 variable scope (变数的作用域) 了。例如以下我们透过 class_eval 和 define_method 帮 String 定义了一个 say 方法,注意到整个 variable scope 都是通透的,没有建立新的 scope:
name = "say"
var = "it’s awesome"
String.class_eval do
define_method(name) do
puts var
end
end
"ihower".say # it’s awesome
class_eval 可以让我们改变 method definition 区域(又叫做 current class)。除了本投影片,建议可以阅读 Metaprogramming in Ruby: It’s Allhe Self 和 Three implicit contexts in Ruby 这两篇文章深入了解 self 和 current class。
8. Class Macro (Ruby’s declarative style)
Class Macro 是 Ruby Meta-programming 非常重要的一个应用,例如在 Rails ActiveRecord 中:
class User <ActiveRecord::Base
validates_presence_of :login
validates_length_of :login,:within =>3..40
validates_presence_of :email
belongs_to :group
has_many :posts
end
1、安装sass
1.安装ruby
因为sass是用ruby语言写的,所以需要安装ruby环境
打开安装包去安装ruby,记住要勾选 下面选项来配置环境路径
Add Ruby executables to your PATH
安装完成之后继续下一步操作
2.安装sass
在cmd里通过gem安装sass
gem是ruby的包管理工具,类似于nodejs 的npm
gem install sass1这个时候如果不翻墙的话是会出问题的,因为:
由于国内网络原因(你懂的),导致 rubygems.org 存放在 Amazon S3 上面的资源文件间歇性连接失败。这时候我们可以通过gem sources命令来配置源,先移除默认的https://rubygems.org源,然后添加淘宝的源https://ruby.taobao.org/,然后查看下当前使用的源是哪个,如果是淘宝的,则表示可以输入sass安装命令gem install sass了
$ gem sources --remove https://rubygems.org/$ gem sources -a https://ruby.taobao.org/ 【如果你系统不支持https,请将淘宝源更换成:gem sources -a http://gems.ruby-china.org】
$ gem sources -l
*** CURRENT SOURCES ***
https://ruby.taobao.org
# 请确保只有 ruby.taobao.org
$ gem install sass1234567
安装好之后执行sass -v就可以看到sass的版本了
实在实在不行,就安装离线文件吧,但是失败率也很高
gem install ./…/sass-3.4.22.gem
2、编译sass文件的方式
1.命令行编译
可以通过cmd命令行执行sass方法来编译
例如:
sass scss/a.scss:css/a.css1sass 后面写要编译的sass文件的路径,‘:’后面写的是
要输出的目录及名字
需要注意的是:必须有这个文件夹才能在里面生成css
这样的话写一句执行一次编译一次有些太麻烦
可以开启一个watch来监听文件变化来进行编译
sass --watch scss:css1–watch表示要监听 :前后的两个都是文件夹,表示scss文件夹的文件改变就编译到css文件夹
2.其他方式编译
除了命令行工具其实还可以用考拉、gulp等工具进行编译,但是ruby和sass是必须要安装的
考拉的方式就不多做介绍了,大家i自己去看一下
gulp的话呢是需要gulp-sass的模块来编译,使用方式类似于gulp-less
这里是网址,点击查看
3、sass四种风格
sass编译的格式
sass编译输出的css有四种格式
nested 嵌套
compact 紧凑
expanded 扩展
compressed 压缩
这些样式会影响输出的css的格式
简单介绍一下:
css默认输出的嵌套
ul{font-size:15px
li{
list-style:none
}
}123456
—》
ul {font-size: 15px}
ul li {
list-style: none}1234
紧凑compact
在编译的时候需要执行
sass --watch scss:css --style compact1这个时候输出的代码就是
ul { font-size: 15px}ul li { list-style: nonepadding: 5px}12
compressed 压缩
在编译的时候需要执行
sass --watch scss:css --style compressed1—>
ul{font-size:15px}ul li{list-style:noneanimation:all 0.4s}1expanded 扩展
更像是平时写的css一样
在编译的时候需要执行
sass --watch scss:css --style expanded1—>
ul {font-size: 15px
}
ul li {
list-style: none
animation: all 0.3s
}1234567
compressed 压缩
更像是平时写的css一样
在编译的时候需要执行
sass --watch scss:css --style compressed1—>
.a{width:100pxheight:100pxborder:1px solid red}.a .b{background:red}14、sass与scss
sass的两个语法版本
sass一开始用的是一种缩进式的语法格式
采用这种格式文件的后缀名是.sass
在sass3.0版本后我们常用的是sassy css语法,扩展名是.scss,更接近与css语法
两个版本的区别
后缀名不同 .sass和.scss
语法不同,请看下面
新版:
/*新版本多行文本注释*/
//新版本
//单行文本注释
@import "base"
@mixin alert{
color:red
background:blue
}
.alert-warning{
@include alert
}
ul{
font-size:15px
li{
list-style:none
}
}123456789101112131415161718
老版本:
/*新版本多行文本注释
//新版本
单行文本注释
@import "base"
=alert
color:red
background:blue
.alert-warning
+alert
ul
font-size:15px
li
list-style:none1234567891011121314
5、变量、嵌套、混合、继承拓展
变量的意义
在sass里我们可以定义多个变量来存放颜色、边框等等的样式,这样就可以在下面想要使用样式的时候使用变量了
这样的优点就是便于维护,更改方便
变量的使用
可以通过$来定义变量,在变量名字中可以使用-和_来作为连接,并且-和_是可以互通的,就是用起来一模一样。
变量的值可以是字符串、数字、颜色等等,在变量里还可以使用其他变量,使用的时候直接写变量名就好了
例如
$primary-color:#ff6600$primary-border:1px solid $primary_color
div.box{
background:$primary-color
}
h1.page-header{
border:$primary-border
}12345678
—》
div.box {background: #ff6600
}
h1.page-header {
border: 1px solid #ff6600
}123456
嵌套的使用
合理的使用嵌套语法,可以使我们编写代码更为快捷
假设我们想写这样的css:
.nav {height: 100px
}
.nav ul {
margin: 0
}
.nav ul li {
float: left
list-style: none
padding: 5px
}1234567891011
在sass里我们可以这样写
.nav{height:100px
ul{
margin:0
li {
float:left
list-style:none
padding:5px
}
}
}1234567891011
大家会发现,写出来的代码父和子之间都有空格隔开,如果我们需要给a加上伪类的话我们这样写
.nav{height:100px
a{
color:#fff
:hover{
color:#ff6600
}
}
}123456789
在里面就会出现这样的情况
.nav a :hover {color: #ff6600
}123
我们发现在a和:hover之间有了空格,这样是不好的,所以我们需要在写的时候在:hover之前把a加上,这样就需要用到在之类里引用父类选择器的方式,我们可以用&符号代替父类
例如:
.nav{height:100px
a{
color:#fff
&:hover{
color:#ff6600
}
}
}123456789
这样就好了,下面来个完整的代码:
.nav{height:100px
ul{
margin:0
li{
float:left
list-style:none
padding:5px
}
a{
display:block
color:#000
&:hover{
color:#f60
background:red
}
}
}
&&-text{
font-size:15px
}
}12345678910111213141516171819202122
-----》
.nav {height: 100px
}
.nav ul {
margin: 0
}
.nav ul li {
float: left
list-style: none
padding: 5px
}
.nav ul a {
display: block
color: #000
}
.nav ul a:hover {
color: #f60
background: red
}
.nav .nav-text {
font-size: 15px
}12345678910111213141516171819202122
嵌套属性
我们可以把一些个复合属性的子属性来嵌套编写,加快编写速度,例如
body{font:{
family:Helvitica
size:15px
weight:bold
}
}
.nav{
border:1px solid red{
left:none
right:none
}
}
.page-next{
transition:{
property:all
delay:2s
}
}12345678910111213141516171819
-----》
body {font-family: Helvitica
font-size: 15px
font-weight: bold
}
.nav {
border: 1px solid red
border-left: none
border-right: none
}
.page-next {
transition-property: all
transition-delay: 2s
}1234567891011121314
mixin 混合
你可以把它想象成一个有名字的定义好的样式
每一个mixin都有自己的名字,类似于js里的函数定义方法如下
@mixin 名字(参数1,参数2...){...
}123
使用方法是在其他选择器css样式里通过@include引入,其实就相当于将mixin里的代码写入到这个选择器的css里,如下:
@mixin alert {color:#f60
background-color:#f60
a{
color:pink
}
&-a{
color:red
}
}
.alert-warning{
@include alert
}12345678910111213
-----》
.alert-warning {color: #f60
background-color: #f60
}
.alert-warning a {
color: pink
}
.alert-warning-a {
color: red
}12345678910
刚才是没有参数的mixin,mixin也可以拥有参数,需要注意的是:
形参的名字前要加$
传参的时候只写值的话要按顺序传
传参的时候不想按顺序的话需要加上形参名字
例如:
@mixin alert($color,$background) {color:$color
background-color:$background
a{
color:darken($color,10%)//把颜色加深百分之十
}
}
.alert-warning{
@include alert(red,blue)
}
.alert-info{
@include alert($background:red,$color:blue)
}12345678910111213
------》
.alert-warning {color: red
background-color: blue
}
.alert-warning a {
color: #cc0000
}
.alert-info {
color: blue
background-color: red
}
.alert-info a {
color: #0000cc
}1234567891011121314
继承拓展 extend
如果我们有一个选择器想要拥有另一个选择所有的东西,不管是样式还是子元素等等,可以使用@extend来继承
大家需要注意的是,++b继承a的时候,a的子元素设置了样式,也会给b的子元素设置样式++,达到完全一样的情况,例如:
.alert {padding:5px
}
.alert a {
font:{
weight:bold
size:15px
}
}
.alert-info {
@extend .alert
backgournd:skyblue
}12345678910111213
----》
.alert, .alert-info {padding: 5px
}
.alert a, .alert-info a {
font-weight: bold
font-size: 15px
}
.alert-info {
backgournd: skyblue
}12345678910
partials
在以前咱们编写css的时候,一个css引入另一个css需要使用@import,其实这是不好的,会多发一次http请求,影响咱们站点的响应速度。
在sass里,咱们可以把小的sass文件分出去,叫做partials,在某个sass里通过@import ‘partials名’去引入,注意路径哟,这样的话就可以把partials里的代码引到咱们大的sass里一起编译
需要注意的是 partials的文件名前要加_
_base.sass :
body{margin:0
padding:0
}1234
style.sass :
@import "base".alert {
padding:5px
}
.alert a {
font:{
weight:bold
size:15px
}
}
.alert-info {
@extend .alert
backgournd:skyblue
}1234567891011121314
----------->
body {margin: 0
padding: 0
}
.alert, .alert-info {
padding: 5px
}
.alert a, .alert-info a {
font-weight: bold
font-size: 15px
}
.alert-info {
backgournd: skyblue
}1234567891011121314
这样的话我们就可以把模块化的思想引入到sass里了
comment注释
sass里的注释有三种
多行注释
单行注释
强制注释
多行注释:压缩后不会出现在css里 /* /
单行注释: 不会出现在css里 //
强制注释:压缩后也会出现在css里 /! */
6、数据类型与函数
数据类型
在sass里有数字、字符串、列表、颜色等类型
在cmd里 输入
sass -i1就会进入到交互模式,输入的计算可以马上得到结果
type-of()可以用来得到数据类型,如:
type-of(5) ->number1注意数字类型的可以包含单位,如:
type-of(5px) ->number1字符串类型:
type-of(hello) ->stringtype-of('hello') ->string12
list类型:
type-of(1px solid red) ->listtype-of(5px 10px) ->list12
颜色:
type-of(red) ->colortype-of(rgb(255,0,0) ->color
type-of(#333) ->color123
number 计算
2+9 -》102*8 -》16
(8/2) ->4 //除法要写括号123
也可以包含单位
5px + 5px ->10px5px -2 ->3px
5px *2 ->10px
5px * 2px ->10px*px //这样就不对了哟
(10px/2px) ->5//除法单位取消
3+2*5px->13px123456
好吧,都是一些小学的数学题,很简单对吧
处理数字的函数
绝对值
abs(10) ->10abs(10px) ->10px
abs(-10px) ->10px123
四舍五入相关
round(3.4)->3 //四舍五入round(3.6)->4
ceil(3.2)->4 //向上取整
ceil(3.6)->4
floor(3.2)->3 //向下取整
floor(3.9)->3
percentage(600px/1000px) ->65% //百分之
min(1,2,3) ->1 //最小值
max(2,3,4,5) ->5 //最大值123456789
字符串相关
//带引号和不带引号的字符串想加为带引号的字符串"a" + b ->"ab"
a + "b" ->"ab"
//字符串+数字
"ab" + 1 ->"ab1"
//字符串 - 和 / 字符串
"a" - b ->"a-b"
"a" / b ->"a/b"
//注意字符串不能相乘123456789
字符串函数
大写:
$word:"hello"to-upper-case($word) ->"HELLO"12
小写:
$word:"Hello"to-lower-case($word) ->"hello"12
得到length:
$word:"Hello"str-length($word) ->512
得到字符串在字符串里的位置:
$word:"Hello"str-index($word,"el") ->212
字符串中插入字符串:
$word:"Hello"str-insert($word,"aa",2) ->"Haaello"12
颜色相关
在sass里除了关键字、十六进制、rgb和rgba之外还有一种颜色是HSL
分别表示的是 色相 0-360(deg) 饱和度 0-100% 明度 0-100%
例如:
body {background-color:hsl(0,100%,50%)
}
-》
body {
background-color: red
}1234567
body {
background-color:hsl(60,100%,50%)
}
-》
body {
background-color: yellow
}1234567
也可以有透明哟
body {background-color:hsl(60,100%,50%,0.5)
}
-》
body {
background-color: rgba(255,255,0,0.5)
}1234567
颜色函数
lighten函数和darken函数可以把颜色加深或减淡,即调整明度,第一个参数为颜色,第二个参数为百分比,例如:
$color:#ff0000$light-color:lighten($color,30%)
$dark-color:darken($color,30%)
.a{
color:$color
background:$light-color
border-color:$dark-color
}12345678
—》
.a {color: #ff0000
background: #ff9999
border-color: #660000
}12345
saturate和desaturate函数可以调整颜色的纯度
$color:hsl(0,50%,50%)$saturate-color:saturate($color,50%)
$desaturate-color:desaturate($color,30%)
.a{
color:$color
background:$saturate-color
border-color:$desaturate-color
}12345678
–》
.a {color: #bf4040
background: red
border-color: #996666
}12345
用transparentize来让颜色更透明
用opatify来让颜色更不透明
$color:rgba(255,0,0,0.5)$opacify-color:opacify($color,0.3)
$transparentize-color:transparentize($color,0.3)
.a{
color:$color
background:$opacify-color
border-color:$transparentize-color
}12345678
—》
.a {color: rgba(255, 0, 0, 0.5)
background: rgba(255, 0, 0, 0.8)
border-color: rgba(255, 0, 0, 0.2)
}12345
列表类型
在sass里,用空格或者逗号隔开的值就是列表类型
如:
1px solid redCourier,microsoft yahei12
列表函数
sass里的列表类似与数组
获取列表的长度length(5px 10x) 2
获取列表中的第几个元素
nth(5px 10px,2) 10px
获取一个元素在一个列表里的下标
index(1px solid red,solid) 2
给列表里加入新的元素
append(5px 10px,5px) 5px 10px 5px
连接两个列表
join(5px 10px,5px 0) 5px 10px 5px 012345678910
map类型
sass里的map类型类似与js里的object
$map:(key1:value1,key2:value2,key3:value3)1map 函数
//定义一个map$color:(light:#ffffff,dark:#000000)
//获取map 的length
length($color) ->2
//得到map里key对应的值
map-get($color,dark) ->#000000
获取map里的所有键的列表
map-keys($color) ->("light","dark") //列表类型
获取map里的所有值的列表
map-values($color) ->("#ffffff","#000000") //列表类型
判断map里是否含有这个key
map-has-key($color,light) ->true
给map里添加键值对
map-merge($color,(light-gray:#cccccc))
->(light:#ffffff,dark:#000000,light-gray:#cccccc)
移除map里的某个键值对
map-remove($colors,light) ->(dark:#000000,light-gray:#cccccc)1234567891011121314151617
boolean类型
在sass里通过><比较得到的值就是布尔值 true 和false
5px>3px ->true5px<2px ->false12
在sass里也可以有或 且 非
且:
(5px >3px) and (5px <2px) ->false(5px >3px) and (5px >2px) ->true12
或:
(5px >3px) or (5px <2px) ->true(5px <3px) and (5px >2px) ->false12
非:
not(5px>3px) ->false1interpolation
在sass里可以通过interpolation的方式来在变量名和属性名上拼接变量值,例如
$name:"info"$attr:"border"
.alert-#{$name}{
#{$attr}-color:red
}12345
---->
.alert-info {border-color: red
}123
7、分支结构、循环结构、函数
分支结构
在sass里,可以使用@if让我们根据一些条件来应用特定的样式
结构:
@if 条件 {
}123
如果条件为真的话,括号里的代码就会释放出来
例如:
$use-refixes:true.rounded{
@if $use-refixes {
-webkit-border-radius:5px
-moz-border-radius:5px
-ms-border-radius:5px
-o-border-radius:5px
}
border-radius:5px
}12345678910
—>
.rounded {-webkit-border-radius: 5px
-moz-border-radius: 5px
-ms-border-radius: 5px
-o-border-radius: 5px
border-radius: 5px
}1234567
如果是另外一种情况
$use-refixes:false1—》
.rounded {border-radius: 5px
}123
if else在sass里的写法是:
body{@if $theme == dark {
background:black
} @else if $theme == light {
background:white
} @else {
background:gray
}
}123456789
for循环
在sass里的for循环是这样的
@for $var form <开始值>through <结束值>{...
}123
还有一种是
@for $var form <开始值>to <结束值>{...
}123
注意,开始值和结束值的关系可以是升序也可以是倒序,但是每次只能+1或者-1
这两种有什么区别呢?
区别就是 from 1 to 4 的话是执行三次,i的变化是 1 2 3
from 1 through 4 的话是执行四次,i的变化是 1 2 3 4
如:
from to
$columns:4@for $i from 1 to $columns{
.col-#{$i}{
width:100% / $columns * $i
}
}123456
—》
.col-1 {width: 25%
}
.col-2 {
width: 50%
}
.col-3 {
width: 75%
}123456789
from through
$columns:4@for $i from 1 through $columns{
.col-#{$i}{
width:100% / $columns * $i
}
}123456
—>
.col-1 {width: 25%
}
.col-2 {
width: 50%
}
.col-3 {
width: 75%
}
.col-4 {
width: 100%
}123456789101112
each 遍历list类型
在sass里可以利用each方法来遍历咱们的list类型的数据
list类型在js里类似于数组,那么each类似于for in遍历,结构如下:
@each $item in $list{...
}123
例如:
$colors:success error warning$map:(success:green,warning:yellow,error:red)
@each $color in $colors{
.bg-#{$color}{
background:map-get($map,$color)
}
}1234567
—>
.bg-success {background: green
}
.bg-error {
background: red
}
.bg-warning {
background: yellow
}123456789
@while 循环
在sass里,拥有@while循环,比@for会更好用一些,@for循环只能从一个数到另一个数变化之间执行,每次变化都是1,while设置循环结构的话更为灵活;
结构:
@while 条件{
}123
eq:
$i:6@while $i>0{
.item-#{$i}{
width:$i*5px
}
$i:$i - 2
}1234567
注意:$i - 2 需要用空格隔开哟
---------》
.item-6 {width: 30px
}
.item-4 {
width: 20px
}
.item-2 {
width: 10px
}123456789
自定义函数
在sass里也可以定义函数,并且也可以有返回值
结构:
@function 名称 (参数1,参数2){@return ...
}123
例如,我们做一个返回map里key对应的值的函数:
$colors:(light:#ffffff,dark:#000000,gray:#555555)@function color($key){
@return map-get($colors,$key)
}
body{
background:color(light)
color:color(dark)
border-color:color(gray)
}123456789
—》
body {background: #ffffff
color: #000000
border-color: #555555
}
微芯片上的器件密度已达到人脑中神经元密度水平。这样水平的微芯片将促使计算机及通信产业更新换代,大大改变人们生产、生活的面貌。科学家们已在讨论把微芯片记忆线路植入人的大脑以治疗老年性痴呆症,或增加人的记忆能力的可能性。用微芯片制做的手提式超级计算机、电子笔记本、微型翻译机和便携式电话等已陆续出现。
微芯片是一种装在与动物组织共容的生化玻璃管中,注写有辨识号码的计算机化芯片。整个微芯片只有米粒大小(13mm ×2.1mm),以无菌方式装在针头内, 以皮下注射的方式植入动物的皮下组织后,可在动物体内永久留存。它提供了动物-安全精确、简便又经济的永久性辨识,能保护宠物在走失或被窃的身份认定。微芯片中注写了绝无重复的一组号码,当遇到感读机所发射的低能量的电磁波时,感读机就会在显示屏上出现芯片上的号码。整个感读过程只需要百万分之几秒的时间即可完成。一旦芯片被植入体内,芯片便会被动物体内所产生的蛋白质包里,终其宠物一生,芯片都会固定于植入部位。芯片不会穿出体外或磨损,也无须更换能源,因此即使在动物体内待着几十年,都不会出问题,使用年限远超过绝大多数的宠物寿命。任何年龄的动物皆可被植入芯片。幼年犬猫在开始进行预防注射计划时,便可植入芯片;鸟类、马及其它宠物则可在任何时候进行芯片植入。
25款震撼世界的微芯片
节选自《IEEE Spectrum》杂志所刊登的《特别报道:25款震撼世界的微芯片》一文。
微芯片设计有时就如同我们的生活一样,有时很小的东西会慢慢积累而变成一件很了不起的东西。设计一个巧妙的微电路,然后将它刻在一片硅上,你的一个小小的杰作就可能会引发一场科技革命。这一切曾经发生在英特尔8088处理器上。Mostek MK4096型4千比特动态随机存取存储器(DRAM)、德州仪器的TMS32010数字信号处理器也曾经引发过科技革命。 在集成电路占统治地位的半个世纪里,许多杰出的微芯片在人们的难以置信中横空出世,然而在这当中,仅有一小部分成为它们中的佼佼者。它们的设计被证明是如此的先进、如此的前卫、如此的超前,以致于我们不得不创造出更多的技术词汇来描述它们。我们甚至可以说是它们为我们带来了让生活变简洁的技术,没有它们我们的生活将变得冗长乏味。
我们在此汇编了一份列有25款集成电路(IC)的名单。在由杰克·基尔比(Jack Kilby)和罗伯特·诺伊斯(Robert Noyce)(注:两人为集成电路的发明者)建造的大厦中,我们认为它们应当被冠以佼佼者的美誉。它们中的一部分成为了芯片发展史中不朽的丰碑。如西格尼蒂克公司的Signetics NE555定时器。它们中的一部分则成为了教科书中的设计范例,如飞兆半导体公司的Fairchild 741运算放大器。它们中的一部分的销售量达到了数十亿,并仍然在继续销售,如微芯科技公司的PIC微控制器。它们中的极小一部分开创出了全新的市场,如东芝的闪存。在它们当中,至少有一个成为了通俗文化中令人讨厌的东西。问题:什么处理器能够为美国动画连续剧《飞出个未来》(Futurama)中的又是酒鬼又是烟枪的坏机器人班德提供动力。答案是:摩斯太克公司的MOS Technology 6502微处理器。
当然,这份名单肯定会存在争议。有些人可能会指责我们选择随意以及过于冗长(这已经不是第一次有人这么指责我们了)。为什么是英特尔的8088微处理器而不是4004(英特尔发布的首款微处理器)或8080(英特尔最著名的微处理器)呢?曾经是许多航天飞机大脑,发热量极低的军用级RCA 1802处理器又排在什么位置呢?
您应当在介绍中明白一件事情,那就是,作者、作者所信任消息人士以及《IEEE Spectrum》杂志多名编辑进行了数周的争论后才编出了这份名单。我们并不准备将每一款获得了商业成功或取得了重大技术改良的微芯片都一一编入名单中。此外,那些虽然设计出色,但是只有五个设计它们的人员才记得的微芯片也不在我们的名单之列。我们只关注那些被证明是独特的,令人着迷的而又使人惊叹的微芯片。我们收入名单的各式各样的微芯片既有大公司设计的也有小公司设计的,在这些公司中,有些拥有很长的历史,有些是最近新成立的。最重要的是,我们收集的是那些为许多人生活带来影响的微芯片,这些微芯片是令人震惊的设备中的一部分,它们象征着技术的发展趋势、令人感到欣喜。
对于每一款微芯片,我们都将会用设计它们的工程师和执行人员的介绍来说明它们的设计经历,以及它们被创新的原因。由于我们不是《IEEE计算史记事》(IEEE Annals of the History of Computing)的工作人员,因此我们不会按年代顺序、按类型或重要性为这25款微芯片进行排序。文章中我们只是以我们认为的便于阅读的顺序随意对这25款微芯片进行了罗列。请注意文章中的25款微芯片的年代顺序是混乱的。
此外,我们还询问了一些杰出技术专家关于他们心目中所喜爱的微芯片。我们甚至想知道在英特尔公司的创始人戈登·摩尔(Gordon Moore)博士和台湾积体电路制造股份有限公司(Taiwan Semiconductor Manufacturing Co.)董事长张忠谋(Morris Chang)心目中哪些IC在具有特别的意义。
我们还想知道您的想法。您是不是为我们的名单中没有您期待的那款微芯片而感到愤怒呢?那么请深吸几口气,泡杯菊花茶,然后加入到我们的讨论中吧。 那是1970年夏季的事情了,它的设计者Hans Camenzind甚至还能回忆起一两件当时关于中国餐馆的事情。在加利福亚州的桑尼维尔的市区,公司有三间办公室,Camenzind的办公室夹在两间办公室中间,面积很小。当时,Camenzind是当地的一家半导体公司――西格尼蒂克公司的顾问。Camenzind当时经济不宽裕,年薪不超过1.5万美元,家里还有妻子和四个孩子。Camenzind当时真的迫切地需要发明出一件杰出的东西。
当然他也是这么做的。事实上,这是一款历史上最杰出的微芯片。555是一个简单的IC,可以作为定时器或振荡器。这款微芯片成为了同类产品中最畅销的产品,很快就大规模的应用于厨房用品、玩具、太空飞船以及成千上万的其它产品上。
现年已经75岁的Camenzind仍然在从事微芯片的设计工作,不过他的家已经不再靠近中国餐馆了。Camenzind回忆称:“当时这个微芯片差一点就没有成功。”
在萌发设计555的想法的时候,Camenzind正在设计一种被称为锁相环的系统。在经过一些修改后,电路可以像一个简单的定时器那样工作。你设定好时间,它就会在一个特定的时期内运行。听起来非常简单,但是做起来并非如此。
首先,西格尼蒂克公司的工程部门拒绝了一想法。因为公司当时正在销售一些部件,而客户可以将这些部件用作定时器。这已经为这一想法画上了句号,不过Camenzind一直坚持着自己的想法。他找到了西格尼蒂克公司的营销经理Art Fury。Fury对这一想法十分欣赏。
为此,Camenzind花了近一年的时间测试电路试验板原型,并在纸上反复划电路,裁剪Rubylith遮蔽膜。Camenzind称:“当时全是手工制作的,没有电脑。”他最后的设计拥有23个晶体管、16个电阻器和2个二极管。
555在1971年投入市场,当时在市场上引起了轰动。西格尼蒂克公司在1975年被飞利浦半导体公司收购,也就是现在的恩智浦半导体。555销售量达到了数十亿部。目前工程师仍然在使用555设计一些有用的模块和一些用处不大的东西,比如为汽车进气格栅设计电影《霹雳游侠》风格的车灯。 如果没有TMC0281,E.T.可能还永远无法“给家里打电话”。这是因为TMC0281是首款单芯片语音合成器,它也是德州仪器推出的“说和拼”( Speak &Spell)学习玩具的“心”(我们是不是应该说是“嘴”呢?)。在史蒂芬·斯皮尔伯格的电影中,外星人用它搭建了自己的行星间发报机(电影中,E.T.还用一衣架、一个咖啡罐和一把圆锯)。
TMC0281使用了一种称为线性预测编码的技术传递声音,声音听起来就像一连串的嗡嗡声、嘶嘶声和邦绑声。当年的四个工程师的Gene A. Frantz目前还在德州仪器。他称,这一令人惊讶的解决方案被认为“不可能通过集成电路完成”。微芯片的改进型被用在了Atari街机游戏和克莱斯勒K-cars中。在2001年,德州仪器将语音合成芯片产线卖给了Sensory公司,后者在2007年晚些时候中止了该产线的生产。如果你需要打一个长距离或很远很远距离的电话,你可以在易趣上花上大约50美元买一个仍处于良好状态的“说和拼”玩具来满足你的需求。 当一个满脸横肉的怪人将这个微芯片装在电脑上,并启动电脑时,整个宇宙都震惊了。这个怪人就是苹果公司创始人之一——斯蒂芬·沃兹尼克,那台电脑就是Apple I,处理器用的是由摩斯太克公司研发的8位微处理器6502。这一处理器同时也是Apple II、the Commodore PET、BBC Micro等经典电脑以及诸如任天堂和Atari等游戏系统的大脑。该处理器的设计者之一Chuck Peddle回忆称,他们是在1975年的一个贸易展示会上推出这款处理器的。他称:“我们用芯片装满了两个玻璃。我和我的妻子就坐在那里卖这些芯片。”6502微处理器终于脱颖而出,其原因是,6502的速度并不比它的竞争对手快多少,但是它的价格便宜,每部售价为25美元,而英特尔的8080和摩托罗拉的6800售价大约在200美元。
与Peddle一起设计6502的Bill Mensch称,突破之处在于将一个最小限度的指令组与制作程序结合在了一起,它的产量是其它竞争产品的10倍。6502迫使处理器价格下降,为个人电脑革命起了推波助澜的作用。如今一些嵌入式系统仍在使用这些芯片。更大的兴趣可能是在《飞出个未来》中, 6502是堕落的机器人班德的大脑,这一信息出现在1999年的剧情中。
在《班德大脑的真象》一文中,《飞出个未来》的电影监制人和主要作者David X. Cohen将解释他为什么将6502选作班德的大脑。 运算放大器都是一些设计相似的硅板。你总是在使用它们中的一些。在几乎所有的事情中你都可以用到它们,它们也会漂亮的完成一些任务。设计者们用它们制作音频和视频的前置放大器、电压比较器、精度校正器、以及许多的其它系统,这些都是日常电子用品的一部分。
在1963年,26岁的工程师Robert Widlar在飞兆半导体公司设计出了首款单片电路的运算放大器IC――μA702。当时每部售价为300美元。随后,Widlar通过改进设计出了μA709,成本也随之削减到了70美元,这使得该款产品获得了巨大的商业成功。故事到了这里,事业如日中天的Widlar要求升职。在要求没有得到满足后,Widlar辞职了。国家半导体公司如获致宝,迅速就雇用了Widlar。在国家半导体公司,Widlar帮助建立了相似的IC设计部门。在1967年,Widlar为国家半导体公司研发出了更好的运算放大器,LM101。
尽管对于突然出现的竞争,飞兆半导体公司管理人员变得焦头烂额,但是在公司的研发实验室里,新加入的David Fullagar对LM101进行了仔细的研究。很快,Fullagar发现虽然LM101的设计非常巧妙,但是还是存在许多缺点。为了避免特定的频率失真,工程师不得不将一个外部电容与芯片联接。此外,由于半导体的质量有波动,导致IC的输入级,也就是所谓的前端使得一些芯片对噪音十分敏感。
他称:“前端看起来有些临时凑合的感觉。”
Fullagar着手开始自己的设计。他拓展了半导体当时的制造程序限制,在芯片中整合了一个30皮法电容。现在如何改良前端呢?解决方案非常的简单,增加了一对额外的晶体管。“在当时,我并不知道如何解决这一问题,我开车去了一趟塔霍湖。”额外的电路使得放大更加平滑,从芯片到芯片变得十分稳定。
Fullagar带着自己设计找到了飞兆半导体公司研发总监Gordon Moore。Moore随后将这一设计送到了公司的商业部门。新的芯片μA741成为了运算放大器的标准。IC和由飞兆半导体公司竞争对手研发的类似产品已经销售了数百万部。以702每部售价300美元的价格你在今天可以买数千个741芯片。 批评家一直嘲笑ICL8038性能有限和运行不规律等毛病。这一正统、直角、三角、锯齿和脉冲波形发生器确定有点不可靠。但是工程师们很快就找到了如何可靠使用这一芯片的方法,随后8038取得了重大成功,最终8038销售了数百万部,并且在不尽其数的应用程序中找到了自己的应用方式,如著名的Moog音乐合成器,以及盗用电路线路者在上世纪八十年代击败电话公司的“蓝盒”等等。8038是如此的热销,以致于Intersil公司出版了一份名为《你一直想知道的关于ICL8038的方方面面》的资料。有这样一个问题:“为什么连接销7至8能够获得最佳的温度性能?”Intersil公司在2002年放弃了8038。但是发烧友至今仍然在收集ICL8038,以自己制造发生器和泰勒明电子琴。
目前Intersil公司公共关系部和公司中最后接触过ICL8038的工程师们都不清楚精确ICL8038的数据。你知道吗? 没有有一种芯片能够将英特尔带入财富500的榜单中呢?英特尔会说有,那就是8088。这是一款16位的CPU,IBM当时把它作为自己独特PC产线的CPU,随后8088统治了桌面电脑市场。
在命运的旋涡中,这款基于著名x86架构的处理器并没有带有“86”。8088只是在英特尔的首款16位CPU 8086的基础上做了轻微改动。在英特尔工程师Stephen Morse推出它后,8088被称为“8086阉割过的版本。”由于新的芯片的主要创新并不是在名称上,它的创新在于8088以16位字处理数据,但是它使用的是8位的外部数据总路线。
在8086设计接近完成时,英特尔管理人员一直对8088项目严格保密。8086 项目的主要工程师Peter A. Stoll也参与了8088的一些设计工作。他称:“管理层甚至不想拖延8086一天,他们怕告诉我们他们已经在脑子里对8088进行了修改会影响8086的完成时间。一天的任务迫使我们要解决以往要花三天时间才能解决的微码漏洞。”
在首个8086被推出后,也就是在英特尔将8086展品和文件运往位于以色列的一个设计部门后,两名工程师Rafi Retter 和Dany Star决定将处理器改为8位总线。
英特尔的Robert Noyce 和Ted Hoff1981年在为《IEEE Micro》杂志写的一篇文章中称,这一修改被证明是英特尔最成功的一个决定。相比较而言,集成了29 000个晶体管的8088需要的晶体管数据减少,相比8086价格更加便宜,在提供了更快的处理速度的同时与8位的硬件完全兼容,可以平稳变换至16位处理器。
首款使用8088的PC是IBM的5150。这款PC当时售价为3000美元。如今全球所有的带有CPU的PC都可以将8088视为老祖宗。这对一款阉割过的芯片,这并不坏。 在iPod之前,曾经出现过Diamond Rio PMP300。PMP300在1998年被推出,一经推立即出现热卖。但是它的凋谢速度比Milli Vanilli还快。不过,这款播放器有一个引人注目的特点是使用了MAS3507 MP3解码芯片。这是一款基于RISC的数字信号处理器,其带有可优化音频压缩和解压缩的指令组。由微开半导体公司研发的MAS3507 MP3解码芯片可以让Rio将数首歌装入自己的闪存中,今天看来有点滑稽,但是当时这足以与便携式CD播放器进行竞争。呵呵,是不是很有趣呢?Rio和它的继承者为iPod铺平了道路。现在你可以装数千首歌,甚至你可以将Milli Vanilli的所有的相册和音乐视频装进你的口袋里。莫斯泰克公司MK4096 4千比特DRAM (1973)
莫斯泰克公司并不是首家推出DRAM的公司,英特尔也曾经推出过。但是莫斯泰克的4千比特DRAM芯片却带有一项重要的创新,被称为地址多路复用技术的电路设计。这一技术是由莫斯泰克的共同创始人Bob Proebsting所设计的。基本上,通过多路寻址信号,该款芯片可使用相同的针脚访问内存的行和列。这使得在内存密度增加后,芯片也不需要更多的针脚,这样一来可以降低成本。这里会有轻微的兼容性问题。4096使用的是16针,而德州仪器、英特尔和摩托罗拉制造的内存是22针。在DRAM史上,这一最大规模对峙之后是什么呢?
莫斯泰克将自己的未来押在了芯片上,它的管理人员开始对客户、合作伙伴、新闻媒体以及自己的雇员进行游说。当时刚被雇用的Fred K. Beckhusen被安排对4096设备进行测试。Beckhusen回忆称,当时Proebsting和首席执行官L.J. Sevin大约在凌晨2点来到他的夜班岗位上与他进行了探讨。Beckhusen称:“他们当时大胆的预测在六个月的时间内,将不再会有人听说或留意22针的DRAM。”他们是正确的。4096和它的继承者们逐渐成为了DRAM的主流。赛灵思公司XC2064 FPGA(现场可编程门阵列) 在上世纪八十年代早期,芯片设计者们一直试图发挥电路中每一个晶体管的功效。不过,Ross Freeman对此却有一个相当激进的想法。他设计了一款满是晶体管的芯片,这些晶体管被松散的组织成逻辑单元。这些逻辑单元可被轮流配置或通过软件被重新配置。有时候,许多晶体管没有被使用。不过,Freeman相信摩尔定律将最终让晶体管真正便宜起来。他赌对了。为了销售被称为现场可编程门阵列也就是FPGA的芯片,Freeman与他人共同创办了赛灵思。该公司的第一款产品XC2064在1985年被推出,当时雇员被分派了一项任务:他们不得不手工绘制一个使用XC2064逻辑单元的范例电路,如同赛灵思的客户一样。赛灵思的前首席技术官Bill Carter回忆首席执行官Bernie Vonderschmitt分派的任务时称:“他在作这一家庭作业时遇到了一些小困难”。Carter非常乐意帮助自己的老板。他称:“我们都在那里,手拿彩色铅笔在纸上做Bernie分派的任务。”今天,赛灵思和其他公司出售的FPGA被用在这份名单中的许多产品上。 Federico Faggin清楚的知道花在销售微处理器上的精力和资金。在英特尔期间,他为两款经典产品原始的4004和8080的设计做出过贡献。当他与前英特尔的同事Ralph Ungermann共同创办齐格洛时,他们决定开始着手设计一个更简单的芯片:单芯片微控制器。
Faggin和Ungermann在加州的洛斯阿图斯市租了一间办公室,开始起草一个商业计划,并开始寻求资本。Faggin回忆称,他们当时在附近的一家名为Safeway超市吃午饭,午饭就是“卡门贝干酪和饼干”。
工程师们很快就发现微处理器市场已经充满了大量设计优秀的芯片。即使他们的芯片比其他公司要出色,他们也只能获得微薄的利润,他们也只能继续吃干酪和饼干。齐格洛不得不把目光放在了食物链的更高层,可以说Z80微处理器项目就是这么诞生的。
他们的目标是做的比8080更出色,并且可以与8080的软件完全兼容,以此吸引客户放弃英特尔。在数个月的时间里,Faggin、 Ungermann和前英特尔工程师Masatoshi Shima在桌子前每周工作80个小时来绘制Z80的电路。Faggin很快发现在设计微芯片时,虽然越小越漂亮,但是这将很伤害眼睛。
他称:“到了最后,我不得不戴上了眼镜。我变成了近视眼了。”
整个设计团队从1975年工作到了1976年。在1976的的3月份,他们完成了一个原型芯片。Z80与摩斯太克公司的6502是同一时代的产品。如同6502一样,他们的成功不仅仅是出现的设计,而且在于价格便宜(大约25美元)。将产品推向市场为他们带来了许多信心。最后还得了胃溃疡的Faggin称:“那是一个令人激动的时刻。”
销售最终取得了成功。Z80用在了数千款产品上,其中包括Osborne I(便携电脑的鼻祖)、Radio Shack TRS?80和MSX家用电脑上。此外,打印机、传真机影印机、调制解调器和卫星上也都有Z80的身影。齐格洛还将Z80用在了一些嵌入式系统中。在一个基本配置中,今天Z80价格为5.73美元,这个价格甚至比一个干酪和饼干午饭还便宜。 很多年前(大约在上世纪八十年代早期)当人们还在穿氖色腿部保温服看“达拉斯”时,微处理器的设计师会就可以寻求增加CPU指令的复杂性,以在每个计算周期内得到更多的计算。加州大学伯克利分校的团队一直都是反传统的先锋,他们的提法刚好相反,他们提出了简化指令组。他们认为,处理指令过快将使得在每个周期内的行为将更少。David Patterson领导的伯克利团队提出了RISC,也就是精简指令集计算机。
作为一个纯理念研究,RISC听起来很具吸引力。但是它可行吗?Sun微系统将赌注押在了这上面。1984年,Sun工程师中的一个小团队开始研发被称为SPARC 的32位RISC处理器(即可扩展性处理架构)。Sun打算将这一芯片用在一个新工作站产品线上。SPARC 项目的顾问Patterson回忆称:“有一天当时的首席执行官Scott McNealy再现在了SPARC的研发实验室里。他说SPARC可以将公司每年5亿美元的收入提升至每年数十亿美元。”
当时研发遇到了很大的压力,许多公司外部人士对Sun能否取得成功表示出怀疑。更糟糕的是Sun的营销团队有一个可怕的认知:SPARC正在由好转坏。为此,研发团队不得不发誓不向其他人员甚至是Sun内部人员透露消息,以免得向竞争对手MIPS Technologies泄露了消息。当时,MIPS Technologies也在探索RISC概念。
当时领导SPARC 设计现任IBM 研究员的Robert Garner回忆称,首个最低版本的SPARC由20 000门阵列处理器组成,其中甚至没有乘/除指令。每秒1000万个指令,这比当时的复杂指令集计算机(CISC)处理器要快三倍。
Sun决定将SPARC用在高利润的工作站和未来即将出现的服务器中。第一款基于SPARC的产品在1987年被推出,为Sun-4系列工作站。这一产品很就占领了市场,并帮助公司突破了10亿美元营收的大关。这一切正如当初McNealy所预测的那样。 当东芝工厂管理员藤尾增冈决定自己重新发明半导体存储器时,闪存的发明传奇也就此打开了序幕。这个我们马上就会有印象。
在闪存出现之前,我们用于存储大量的数据不得不利用磁带、软盘和硬盘。许多公司在努力设计出一种固态代替方案。但是诸如EPROM(需要紫外线擦除器来擦除数据)和EEPROM等方案并不能有效的存储大量数据。
在1980年,藤尾增冈招聘了四名工程师启动了一个半秘密的项目以研发一个存储芯片,实现存储大量数据,并且让用户可以买得起。他们的战备非常简单。目前担任东京Unisantis Electronics首席技术官的藤尾增冈称:“我们知道只要晶体管在尺寸上降下了了,那么芯片的成本也将会下降。”
藤尾增冈的团队推出了一款EEPROM的改良产品,记忆单元由一单个晶体管组成。在当时,常规的EEPROM每个记忆单元需要两个晶体管。这个小小的不同对价格带来了巨大的影响。
为了起一个便于记住的名字,他们将这个芯片称为“flash”,这个名字也是因为芯片的超快擦除能力。现在,你会认为东芝会迅速将这一发明投入生产,并看着这一发明为公司带来的滚滚财富,这里你可能不清楚大公司的内部研发情况。当这一发现成功后,藤尾增冈的老板告诉他,好了,忘掉这个发明吧。
当然,藤尾增冈不会忘掉这个发明。在1984年,藤尾增冈带着他的存储市场图纸参加了在旧金山召开的IEEE国际电子设备大会。这提醒英特尔开始研发基于“非或”逻辑门的闪存。在1988年,英特尔推出了一款256K芯片,这款芯片能够用于汽车、电脑和其他设备之中。这为英特尔带来了一个崭新的业务。
这促使东芝决定将藤尾增冈的发明进行营销。藤尾增冈的闪存芯片基于NAND技术,这一技术可以提供更高容量的存储,并且被证明更容易制造。在1989年,最终取得了成功,当时东芝的首款NAND闪存投入市场。事实正如藤尾增冈所预测的那样,价格出现了下降。
在上世纪九十年代末期,数码摄影推出了闪存的应用。东芝也因此成为了这一价值达数十亿美元市场中的最大参与者。与此同时,藤尾增冈与东芝中的其他管理人员的关系恶化,最终,藤尾增冈辞职离开了东芝。
现在NAND闪存已经成为了手机、照相机和音乐播放器中重要的设备。