Skip to content

函数

¥Functions

Stylus 具有强大的语言内函数定义。函数定义看起来与 mixin 相同;但是,函数可能会返回一个值。

¥Stylus features powerful in-language function definitions. Function definitions appear identical to mixins; however, functions may return a value.

返回值

¥Return Values

让我们尝试一个简单的例子:创建一个将两个数字相加的函数。

¥Let's try a trivial example: creating a function that adds two numbers.

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

然后我们可以在条件、属性值等中使用这个函数。

¥We can then use this function in conditions, in property values, etc.

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

渲染:

¥Rendering:

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

参数默认值

¥Argument Defaults

可选参数可以默认为给定的表达式。使用 Stylus,我们甚至可以将参数默认为之前的参数!

¥Optional arguments may default to a given expression. With Stylus we may even default arguments to earlier arguments!

例如:

¥For example:

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

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

¥Note: Since argument defaults are assignments, we can also use function calls for defaults:

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

命名参数

¥Named Parameters

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

¥Functions accept named parameters. This frees you from remembering the order of parameters, or simply improves the readability of your code.

例如:

¥For example:

subtract(a, b)
  a - b

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

subtract(b: 10, a: 25)

函数体

¥Function Bodies

我们可以进一步完善简单的 add() 函数。让我们通过内置的 unit() 来铸造所有作为 px 传递的单位。它重新分配每个参数,并提供一个单位类型字符串(或标识符),它忽略单位转换。

¥We can take our simple add() function further. Let's casting all units passed as px via the unit() built-in. It reassigns each argument, and provides a unit-type string (or identifier), which ignores unit conversion.

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

多个返回值

¥Multiple Return Values

Stylus 函数可以返回多个值,就像你可以为变量分配多个值一样。

¥Stylus functions can return several values—just as you can assign several values to a variable.

例如,以下是有效的分配:

¥For example, the following is a valid assignment:

sizes = 15px 10px

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

sizes[0]
// => 15px 

同样,我们可能会返回几个值:

¥Similarly, we may return several values:

sizes()
  15px 10px

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

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

一个轻微的例外是返回值是标识符时。例如,以下内容看起来像是对 Stylus 的属性分配(因为不存在运算符):

¥One slight exception is when return values are identifiers. For example, the following looks like a property assignment to Stylus (since no operators are present):

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

为了消除歧义,我们可以用括号括起来,或者使用 return 关键字:

¥To disambiguate, we can either wrap with parentheses, or use the return keyword:

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 是否是一个字符串,或者一个 ident(类似于字符串)。由于未定义的标识符将自身作为值生成,因此我们可以将它们与自身进行比较,如下所示(其中使用 yesno 代替 truefalse):

¥Let's say we want to create a function named stringish() to determine whether the argument can be transformed to a string. We check if val is a string, or an ident (which is string-like). Because undefined identifiers yield themselves as the value, we may compare them to themselves as shown below (where yes and no are used in place of true and false):

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

用法:

¥Usage:

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 不是布尔字面量。在这种情况下,它们只是未定义的标识符。

¥note: yes and no are not boolean literals. They are simply undefined identifiers in this case.

另一个例子:

¥Another example:

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

用法:

¥Usage:

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(),如下所示:

¥To alias a function, simply assign a function's name to a new identifier. For example, our add() function could be aliased as plus(), like so:

plus = add

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

plus(1, 2)
// => 3

变量函数

¥Variable Functions

就像我们可以 "alias" 一个函数一样,我们也可以传递一个函数。在这里,我们的 invoke() 函数接受一个函数,因此我们可以向它传递 add()sub()

¥In the same way that we can "alias" a function, we can pass a function as well. Here, our invoke() function accepts a function, so we can pass it add() or 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)

产量:

¥Yielding:

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

匿名函数

¥Anonymous functions

你可以在需要时使用 @(){} 语法使用匿名函数。以下是如何使用它来创建自定义 sort() 函数:

¥You can use anonymous functions where needed using @(){} syntax. Here is how you could use it to create a custom sort() function:

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 局部变量可用于所有函数体,并包含传递的所有参数。

¥The arguments local is available to all function bodies, and contains all the arguments passed.

例如:

¥For example:

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 Example

下面我们定义了 get(hash, key) 函数,它返回 key(或 null)的值。我们迭代 hash 中的每个 pair,当第一个(key)匹配时返回该对的第二个节点。

¥Below we define the get(hash, key) function, which returns the value of key (or null). We iterate each pair in hash, returning the pair's second node when the first (the key) matches.

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 表达式相结合可以提供极大的灵活性:

¥As demonstrated below, in-language functions—paired with robust Stylus expressions—can provide great flexibility:

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