Разделить модули F # на несколько файлов

Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException вообще.

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

25
задан TimothyP 27 April 2009 в 13:41
поделиться

4 ответа

По-видимому, нет:

C:\temp\Tim>type 1.fs 2.fs

1.fs


#light
module Module

let sayHello1 = printfn "Hello, "

2.fs


#light
module Module

let sayHello2 = printfn "world!"

C:\temp\Tim>fsc 1.fs 2.fs
Microsoft F# Compiler, (c) Microsoft Corporation, All Rights Reserved
F# Version 1.9.6.2, compiling for .NET Framework Version v2.0.50727

2.fs(2,1): error FS0191: An implementation of the file or module Module has already been given.

Обновление: ошибка изменилась в F # 4.0, теперь она является:

Ошибка FS0248: Два модуля с именем «Модуль» встречаются в двух частях этой сборки

где Модуль - это полное имя вашей сборки, включая часть пространства имен.

11
ответ дан 28 November 2019 в 05:44
поделиться

Как говорит Курт, вы можете добавлять методы расширения к типам, и, таким образом,

// File1.fs
namespace Foo

type Mine() =
    static member f1 () = ()

затем

// File2.fs
type Foo.Mine with
    static member f2() = ()

Foo.Mine.    // both f1 and f2 here

Поскольку это класс, а не модуль, вы теряете возможность делать «открытую шахту». (но получить способность перегрузки); таким образом, это может или не может быть приемлемой альтернативой для вас, в зависимости от того, что именно вы делаете.

4
ответ дан 28 November 2019 в 05:44
поделиться

Иногда я делю тип на несколько мест, например:

module Foo

type Partial = Bar | BarInt of int

module Bar

type Foo.Partial with
    member x.Extend = 5


let b = Foo.Bar.Extend

где модули Foo и Bar находятся в разных файлах.

3
ответ дан 28 November 2019 в 05:44
поделиться

The type extensions are cool, and hopefully they will allow to be cross file, while still being intrinsic. If you do a type extension in the same file, it compiles to one class, and the extension has access to private members and so on. If you do it in another file, it's just an "optional" extension, like C# static extension methods. (Even though the F# specs say differently.)

I'd be surprised if this isn't addressed at some point, if only for designer support. If intrinsic type extensions could be anywhere in the assembly, that'd be pretty slick.

Another option, which might not be what you want, is to create a type and a module, call the module the same name, and then add the ModuleSuffix flag to it:

type Foo() = 
    static member Bar = 1

[<CompilationRepresentationAttribute(CompilationRepresentationFlags.ModuleSuffix)>]
module Foo =
    let Baz = 2

printfn "%d %d" Foo.Bar Foo.Baz

This is used in the F# libraries, so they can have a type List or whatever, along with tons of helper stuff in a module.

7
ответ дан 28 November 2019 в 05:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: