Julia 0.5.0 发布了,本次更新包括了很多新的语言特性。


图片 1Functions.gif



图片 2


Babel plugin for Vue 2.0 JSX

Functions in Kotlin are declared using the fun keyword:



  • Assumes you are using Babel with a module bundler e.g. Webpack,
    because the spread merge helper is imported as a module to avoid

  • This is mutually exclusive with babel-plugin-transform-react-jsx.

fun double: Int { return 2 * x}
  • Generator expressions: `f(i) for i in 1:n` ([#4470]). This
    returns an iterator that computes the specified values on demand.
    This is useful for computing, e.g.

  • `sum(f(i) for i in 1:n)` without creating an intermediate array of

  • Generators and comprehensions support filtering using `if`
    ([#550]) and nested iteration using multiple `for` keywords

  • Fused broadcasting syntax: “f.(args…)“ is equivalent to
    “broadcast(f, args…)“ ([#15032]), and nested
    `f.(g.(args…))` calls are fused into a single `broadcast` loop

  • Similarly, the syntax `x .= …` is equivalent to a
    `broadcast!(identity, x, …)`call and fuses with nested “dot”
    calls; also, `x .+= y` and similar is now equivalent to `x .= x
    .+ y`, rather than `x = x .+ y` ([#17510]).

  • Macro expander functions are now generic, so macros can have
    multiple definitions(e.g. for different numbers of arguments, or
    optional arguments) ([#8846], [#9627]).

  • However note that the argument types refer to the syntax tree
    representation, and not to the types of run time values.

  • Varargs functions like `foo{T}(x::T…)` may now restrict the
    number of such arguments using `foo{T,N}(x::Vararg{T,N})`

  • `x ∈ X` is now a synonym for `x in X` in `for` loops and
    comprehensions, as it already was in comparisons ([#13824]).

  • The `PROGRAM_FILE` global is now available for determining the
    name of the running script ([#14114]).

  • The syntax `x.:sym` (e.g. `Base.:+`) is now supported, while
    using `x.(:sym)` or `x.(i)` for field access are deprecated in
    favor of `getfield` ([#15032]).

  • Function return type syntax `function f()::T` has been added
    ([#1090]). Values returned from a function with such a
    declaration will be converted to the specified type `T`.

  • Many more operators now support `.` prefixes (e.g. `.≤`)
    ([#17393]).  However, users are discouraged from overloading
    these, since they are mainly parsed in order to implement backwards
    compatibility with planned automatic broadcasting of dot operators
    in Julia 0.6 ([#16285]).  Explicitly qualified operator names
    like `Base.≤` should now use `Base.:≤` (prefixed by
    `@compat` if you need 0.4 compatibility via the `Compat`

  • User-extensible bounds check elimination is now possible with the
    new `@boundscheck` macro ([#14474]). This macro marks bounds
    checking code blocks, which the compiler may remove when encountered
    inside an `@inbounds` call.


npm install

In your .babelrc:

  "presets": ["es2015"],
  "plugins": ["transform-vue-jsx"]

The plugin transpiles the following JSX:

<div id="foo">{this.text}</div>

To the following JavaScript:

h('div', {
  attrs: {
    id: 'foo'
}, [this.text])

Note the h function, which is a shorthand for a Vue instance’s
$createElement method, must be in the scope where the JSX is. Since
this method is passed to component render functions as the first
argument, in most cases you’d do this:

Vue.component('jsx-example', {
  render (h) { // <-- h must be in scope
    return <div id="foo">bar</div>

Calling functions uses the traditional approach:


h auto-injection

Starting with version 3.4.0 we automatically inject
const h = this.$createElement in any method and getter (not functions
or arrow functions) declared in ES2015 syntax that has JSX so you can
drop the (h) parameter.

Vue.component('jsx-example', {
  render () { // h will be injected
    return <div id="foo">bar</div>
  myMethod: function () { // h will not be injected
    return <div id="foo">bar</div>
  someOtherMethod: () => { // h will not be injected
    return <div id="foo">bar</div>

class App extends Vue {
  get computed () { // h will be injected
    return <div id="foo">bar</div>
val result = double


Difference from React JSX

First, Vue 2.0’s vnode format is different from React’s. The second
argument to the createElement call is a “data object” that accepts
nested objects. Each nested object will be then processed by
corresponding modules:

render (h) {
  return h('div', {
    // Component props
    props: {
      msg: 'hi'
    // normal HTML attributes
    attrs: {
      id: 'foo'
    // DOM props
    domProps: {
      innerHTML: 'bar'
    // Event handlers are nested under "on", though
    // modifiers such as in v-on:keyup.enter are not
    // supported. You'll have to manually check the
    // keyCode in the handler instead.
    on: {
      click: this.clickHandler
    // For components only. Allows you to listen to
    // native events, rather than events emitted from
    // the component using vm.$emit.
    nativeOn: {
      click: this.nativeClickHandler
    // class is a special module, same API as `v-bind:class`
    class: {
      foo: true,
      bar: false
    // style is also same as `v-bind:style`
    style: {
      color: 'red',
      fontSize: '14px'
    // other special top-level properties
    key: 'key',
    ref: 'ref',
    // assign the `ref` is used on elements/components with v-for
    refInFor: true,
    slot: 'slot'

The equivalent of the above in Vue 2.0 JSX is:

render (h) {
  return (
      // normal attributes or component props.
      // DOM properties are prefixed with `domProps`
      // event listeners are prefixed with `on` or `nativeOn`
      // other special top-level properties
      class={{ foo: true, bar: false }}
      style={{ color: 'red', fontSize: '14px' }}
      // assign the `ref` is used on elements/components with v-for

Calling member functions uses the dot notation:

Component Tip

If a custom element starts with lowercase, it will be treated as a
string id and used to lookup a registered component. If it starts with
uppercase, it will be treated as an identifier, which allows you to do:

import Todo from './Todo.js'

export default {
  render (h) {
    return <Todo/> // no need to register Todo via components option
Sample // create instance of class Sample and call foo

文章转载自:开源中国社区 []    

JSX Spread

JSX spread is supported, and this plugin will intelligently merge nested
data properties. For example:

const data = {
  class: ['b', 'c']
const vnode = <div class="a" {...data}/>

The merged data will be:

{ class: ['a', 'b', 'c'] }


Function parameters are defined using Pascal notation, i.e. name:
type. Parameters are separated using commas. Each parameter must be
explicitly typed:

fun powerOf(number: Int, exponent: Int) { ... }

Vue directives

Note that almost all built-in Vue directives are not supported when
using JSX, the sole exception being v-show, which can be used with the
v-show={value} syntax. In most cases there are obvious programmatic
equivalents, for example v-if is just a ternary expression, and
v-for is just an array.map() expression, etc.

For custom directives, you can use the v-name={value} syntax. However,
note that directive arguments and modifiers are not supported using this
syntax. There are two workarounds:

  1. Pass everything as an object via value, e.g.
    v-name={{ value, modifier: true }}

  2. Use the raw vnode directive data format:

const directives = [
  { name: 'my-dir', value: 123, modifiers: { abc: true } }

return <div {...{ directives }}/>


Function parameters can have default values, which are used when a
corresponding argument is omitted. This allows for a reduced number of
overloads compared toother languages:

fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) { ... }

Default values are defined using the = after type along with the

Overriding methods always use the same default parameter values as the
base method.When overriding a method with default parameters values, the
default parameter values must be omitted from the signature:

open class A { open fun foo(i: Int = 10) { ... }}class B : A() { override fun foo { ... } // no default value allowed}

If a default parameter precedes a parameter with no default value, the
default value can be used only by calling the function with named

fun foo(bar: Int = 0, baz: Int) { ... }foo // The default value bar = 0 is used

But if a last argument lambda is passed to a function call outside the
parentheses, passing no values for the default parameters is allowed:

fun foo(bar: Int = 0, baz: Int = 1, qux: () -> Unit) { ... }foo { println } // Uses the default value baz = 1 foo { println } // Uses both default values bar = 0 and baz = 1

Named Arguments

Function parameters can be named when calling functions. This is very
convenient when a function has a high number of parameters or default

Given the following function:

fun reformat(str: String, normalizeCase: Boolean = true, upperCaseFirstLetter: Boolean = true, divideByCamelHumps: Boolean = false, wordSeparator: Char = ' ') {...}

we could call this using default arguments:


However, when calling it with non-default, the call would look something

reformat(str, true, true, false, '_')

With named arguments we can make the code much more readable:

reformat(str, normalizeCase = true, upperCaseFirstLetter = true, divideByCamelHumps = false, wordSeparator = '_')

and if we do not need all arguments:

reformat(str, wordSeparator = '_')

When a function is called with both positional and named arguments, all
the positional arguments should be placed before the first named one.
For example, the call f is allowed, but f is not.

Variable number of arguments (vararg{: .keyword }) can be passed in
the named form by using the spread operator:

fun foo(vararg strings: String) { ... }foo(strings = *arrayOf("a", "b", "c"))

Note that the named argument syntax cannot be used when calling Java
functions, because Java bytecode does notalways preserve names of
function parameters.

Unit-returning functions

If a function does not return any useful value, its return type is
Unit. Unit is a type with only one value – Unit. Thisvalue does
not have to be returned explicitly:

fun printHello(name: String?): Unit { if (name != null) println("Hello ${name}") else println("Hi there!") // `return Unit` or `return` is optional}

The Unit return type declaration is also optional. The above code is
equivalent to:

fun printHello(name: String?) { ... }

Single-Expression functions

When a function returns a single expression, the curly braces can be
omitted and the body is specified after a = symbol:

fun double: Int = x * 2

Explicitly declaring the return type is optional when this can be
inferred by the compiler:

fun double = x * 2

Explicit return types

Functions with block body must always specify return types explicitly,
unless it’s intended for them to return Unit, in which case it is
optional.Kotlin does not infer return types for functions with block
bodies because such functions may have complex control flow in the body,
and the returntype will be non-obvious to the reader (and sometimes even
for the compiler).

Variable number of arguments

A parameter of a function (normally the last one) may be marked with
vararg modifier:

fun <T> asList(vararg ts: T): List<T> { val result = ArrayList<T>() for  // ts is an Array result.add return result}

allowing a variable number of arguments to be passed to the function:

val list = asList

Inside a function a vararg-parameter of type T is visible as an
array of T, i.e. the ts variable in the example above has type
Array<out T>.

Only one parameter may be marked as vararg. If a vararg parameter is
not the last one in the list, values for thefollowing parameters can be
passed using the named argument syntax, or, if the parameter has a
function type, by passinga lambda outside parentheses.

When we call a vararg-function, we can pass arguments one-by-one, e.g.
asList, or, if we already have an arrayand want to pass its contents
to the function, we use the spread operator (prefix the array with

val a = arrayOfval list = asList(-1, 0, *a, 4)

Infix notation

Functions marked with the infix{: .keyword } keyword can also be
called using the infix notation (omitting the dot and the parentheses
for the call). Infix functions must satisfy the following requirements:

  • They must be member functions or extension functions;
  • They must have a single parameter;
  • The parameter must not accept variable number of arguments and must
    have no default value.

infix fun Int.shl: Int { ... }// calling the function using the infix notation1 shl 2// is the same as1.shl

Infix function calls have lower precedence than the arithmetic
operators, type casts, and the rangeTo operator.The following
expressions are equivalent:

  • 1 shl 2 + 3 and 1 shl
  • 0 until n * 2 and 0 until
  • xs union ys as Set<*> and xs union (ys as Set<*>)

On the other hand, infix function call’s precedence is higher than
that of the boolean operators && and ||, is– and in-checks,
and some other operators. These expressions are equivalent as well:

  • a && b xor c and a &&
  • a xor b in c and in c

See the Grammar reference for the complete operators precedence

Note that infix functions always require both the receiver and the
parameter to be specified. When you’recalling a method on the current
receiver using the infix notation, you need to use this explicitly;
unlike regular method calls,it cannot be omitted. This is required to
ensure unambiguous parsing.

class MyStringCollection { infix fun add(s: String) { ... } fun build() { this add "abc" // Correct add // Correct add "abc" // Incorrect: the receiver must be specified }}

In Kotlin functions can be declared at top level in a file, meaning you
do not need to create a class to hold a function, which you are required
to do in languages such as Java, C# or Scala. In additionto top level
functions, Kotlin functions can also be declared local, as member
functions and extension functions.

Local Functions

Kotlin supports local functions, i.e. a function inside another

fun dfs(graph: Graph) { fun dfs(current: Vertex, visited: Set<Vertex>) { if (!visited.add return for (v in current.neighbors) dfs(v, visited) } dfs(graph.vertices[0], HashSet}

Local function can access local variables of outer functions (i.e. the
closure), so in the case above, the visited can be a local variable:

fun dfs(graph: Graph) { val visited = HashSet<Vertex>() fun dfs(current: Vertex) { if (!visited.add return for (v in current.neighbors) dfs } dfs(graph.vertices[0])}

Member Functions

A member function is a function that is defined inside a class or

class Sample() { fun foo() { print }}

Member functions are called with dot notation:

Sample // creates instance of class Sample and calls foo

For more information on classes and overriding members see Classes and

Functions can have generic parameters which are specified using angle
brackets before the function name:

fun <T> singletonList: List<T> { ... }

For more information on generic functions see Generics.

Inline functions are explained here.

Extension functions are explained in their own section.

Higher-Order functions and Lambdas are explained in their own section.

Kotlin supports a style of functional programming known as tail
recursion.This allows some algorithms that would normally be written
using loops to instead be written using a recursive function, but
without the risk of stack overflow.When a function is marked with the
tailrec modifier and meets the required form, the compiler optimises
out the recursion, leaving behind a fast and efficient loop based
version instead:

val eps = 1E-10 // "good enough", could be 10^-15tailrec fun findFixPoint(x: Double = 1.0): Double = if (Math.abs(x - Math.cos < eps) x else findFixPoint(Math.cos

This code calculates the fixpoint of cosine, which is a mathematical
constant. It simply calls Math.cos repeatedly starting at 1.0 until the
result doesn’t change any more, yielding a result of 0.7390851332151611
for the specified eps precision. The resulting code is equivalent to
this more traditional style:

val eps = 1E-10 // "good enough", could be 10^-15private fun findFixPoint(): Double { var x = 1.0 while  { val y = Math.cos if (Math.abs < eps) return x x = Math.cos }}

To be eligible for the tailrec modifier, a function must call itself
as the last operation it performs. You cannot use tail recursion when
there is more code after the recursive call, and you cannot use it
within try/catch/finally blocks. Currently tail recursion is only
supported in the JVM backend.

国内第一Kotlin 开发者社区公众号,主要分享、交流 Kotlin 编程语言、Spring

图片 3开发者社区