Skip to content

函数(Functions)

Stylus强大之处就在于其内置的语言函数定义。其定义与混入(mixins)一致;却可以返回值。

返回值

很简单的例子,两数值相加的函数:

add(a, b)
  a + b
add(a, b)
  a + b

我们可以在特定条件下使用该方法,如在属性值中:

body
  padding add(10px, 5)
body
  padding add(10px, 5)

编译为:

body {
  padding: 15px;
}
body {
  padding: 15px;
}

默认参数

可选参数往往有个默认的给定表达。在Stylus中,我们甚至可以超越默认参数。

示例:

add(a, b = a)
  a + b

add(10, 5)
// => 15

add(10)
// => 20
add(a, b = a)
  a + b

add(10, 5)
// => 15

add(10)
// => 20

注意: 因为参数默认是赋值,我们可以使用函数调用作为默认值:

add(a, b = unit(a, px))
  a + b
add(a, b = unit(a, px))
  a + b

命名参数

函数接受命名参数。这使您不必记住参数的顺序,或者只是提高代码的可读性。

示例:

subtract(a, b)
  a - b

subtract(b: 10, a: 25)
subtract(a, b)
  a - b

subtract(b: 10, a: 25)

函数体

我们可以把简单的add()方法更进一步。通过内置unit()把单位都变成px, 因为赋值在每个参数上,因此,我们可以无视单位换算。

add(a, b = a)
  a = unit(a, px)
  b = unit(b, px)
  a + b

add(15%, 10deg)
// => 25
add(a, b = a)
  a = unit(a, px)
  b = unit(b, px)
  a + b

add(15%, 10deg)
// => 25

多个返回值

Stylus的函数可以返回多个值,就像你给变量赋多个值一样。

例如,下面就是一个有效赋值:

sizes = 15px 10px

sizes[0]
// => 15px
sizes = 15px 10px

sizes[0]
// => 15px

类似的,我们可以在函数中返回多个值:es:

sizes()
  15px 10px

sizes()[0]
// => 15px
sizes()
  15px 10px

sizes()[0]
// => 15px

有个小小的例外就是返回值是标识符。例如,下面看上去像一个属性赋值给Stylus(因为没有操作符):

swap(a, b)
  b a
swap(a, b)
  b a

避免歧义,我们可以使用括号,或是return关键字:

swap(a, b)
  (b a)

swap(a, b)
  return b a
swap(a, b)
  (b a)

swap(a, b)
  return b a

条件(Conditionals)

比方说,我们想要创建一个名为stringish()的函数,用来决定参数是否是字符串。我们检查val是否是字符串或缩进(类似字符)。因为未定义的标识符将自己作为值,我们可以将它们与自己进行比较,如下,使用yesno代替truefalse

stringish(val)
  if val is a 'string' or val is a 'ident'
    yes
  else
    no
stringish(val)
  if val is a 'string' or val is a 'ident'
    yes
  else
    no

用法:

stringish('yay') == yes
// => true

stringish(yay) == yes
// => true

stringish(0) == no
// => true
stringish('yay') == yes
// => true

stringish(yay) == yes
// => true

stringish(0) == no
// => true

注意: yesno并不是布尔值。本例中,它们只是简单的未定义标识符。

另一个例子:

compare(a, b)
  if a > b
    higher
  else if a < b
    lower
  else
    equal
compare(a, b)
  if a > b
    higher
  else if a < b
    lower
  else
    equal

用法:

compare(5, 2)
// => higher

compare(1, 5)
// => lower

compare(10, 10)
// => equal
compare(5, 2)
// => higher

compare(1, 5)
// => lower

compare(10, 10)
// => equal

别名(Aliasing)

给函数起个别名,相当简单,直接赋值就可以了。例如上面的add()弄个别名plus(), 如下:

plus = add

plus(1, 2)
// => 3
plus = add

plus(1, 2)
// => 3

变量函数(Variable Functions)

我们可以把函数当作变量传递到新的函数中。例如,invoke()接受函数作为参数,因此,我们可以传递add()以及sub().

add(a, b)
  a + b

sub(a, b)
  a - b

invoke(a, b, fn)
  fn(a, b)

body
  padding invoke(5, 10, add)
  padding invoke(5, 10, sub)
add(a, b)
  a + b

sub(a, b)
  a - b

invoke(a, b, fn)
  fn(a, b)

body
  padding invoke(5, 10, add)
  padding invoke(5, 10, sub)

输出:

body {
  padding: 15;
  padding: -5;
}
body {
  padding: 15;
  padding: -5;
}

匿名函数(Anonymous functions)

可以使用 @(){} 语法来使用匿名函数. 这是一个演示如何创建sort()函数的例子:

sort(list, fn = null)
  // default sort function
  if fn == null
    fn = @(a, b) {
      a > b
    }

  // bubble sort
  for $i in 1..length(list) - 1
    for $j in 0..$i - 1
      if fn(list[$j], list[$i])
        $temp = list[$i]
        list[$i] = list[$j]
        list[$j] = $temp
  return list

  sort('e' 'c' 'f' 'a' 'b' 'd')
  // => 'a' 'b' 'c' 'd' 'e' 'f'

  sort(5 3 6 1 2 4, @(a, b){
    a < b
  })
  // => 6 5 4 3 2 1
sort(list, fn = null)
  // default sort function
  if fn == null
    fn = @(a, b) {
      a > b
    }

  // bubble sort
  for $i in 1..length(list) - 1
    for $j in 0..$i - 1
      if fn(list[$j], list[$i])
        $temp = list[$i]
        list[$i] = list[$j]
        list[$j] = $temp
  return list

  sort('e' 'c' 'f' 'a' 'b' 'd')
  // => 'a' 'b' 'c' 'd' 'e' 'f'

  sort(5 3 6 1 2 4, @(a, b){
    a < b
  })
  // => 6 5 4 3 2 1

参数(arguments)

arguments是所有函数体都有的局部变量,包含传递的所有参数。

例如

sum()
  n = 0
  for num in arguments
    n = n + num

sum(1,2,3,4,5)
// => 15
sum()
  n = 0
  for num in arguments
    n = n + num

sum(1,2,3,4,5)
// => 15

Hash示例

下面,我们定义get(hash, key)方法,用来返回key值或null. 我们遍历每个键值对,如果键值匹配,返回对应的值。

get(hash, key)
  return pair[1] if pair[0] == key for pair in hash
get(hash, key)
  return pair[1] if pair[0] == key for pair in hash

下面例子可以证明,语言函数模样的Stylus表达式具有更大的灵活性:

hash = (one 1) (two 2) (three 3)

get(hash, two)
// => 2

get(hash, three)
// => 3

get(hash, something)
// => null
hash = (one 1) (two 2) (three 3)

get(hash, two)
// => 2

get(hash, three)
// => 3

get(hash, something)
// => null