スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

F#入門基本編落穂拾い その30 モジュール、名前空間(2) 外部からの参照

今回は、モジュールvisual studioでF#のクラスライブラリを作り、それをF#の他のプロジェクトから参照するときの、参照方法について、少しふれておきたいと思います。
 
クラスライブラリをつくるプロジェクト名をForBlogLibとしておき、このライブラリを利用する側のプロジェクト名をForBlogとしておきます。
(Visual studioでクラスライブラリを作る場合は、プロジェクトの作成で「F# Library」を選択するか、すでにF# Applicationを選択してファイルを作成している場合はsolution Explorerでプロジェクト名を右クリックし、プロパティを選択し、Output typeを Class Libraryに変更します。)
ForBlog側ではSolution ExplorerでForBlogLib側で作成したdllへの参照を追加しておきます。
 
 

(ライブラリ側)
module Module1
 
let myVal = 3
module localModule1 =
    let myVal = 5
    type MyType =
        | Num of int
 
(使用する側)
Module1.と打つと候補が現れます。

let t0 = Module1.myVal  //t0は3
let t1 = Module1.localModule1.myVal //t1は5
let t2 = Module1.localModule1.Num(3)
 
(注意)Solution Explorerで参照を設定しても、F# Interactive内で参照が設定されるわけではないので、F# Interactive でもModule1を使用するには
 
>#r @"C:\ディレクトリ\ファイル名.dll";;
 
というように参照を追加する必要があります。
 
またopen  Module1としておけば、
上は
open Module1
let t0 = myVal
let t1 = localModule1.myVal
 
と書き直せますが、localModule1.myValのような部分名はトラブルのもとなので、ドットなしの名前で参照できない値については、Module1.localModule1.myValのような完全名を使う方が推奨です。
 
次に名前空間も使用する場合を紹介します。
 

(ライブラリ側)
namespace myName1
 
type MyType =
      | Num of int
 
module localModule1 =
    let myVal = 1
 
module localModule2 =
    let myVal = 2
 
(使用する側)
let t0 = myName1.Num(5)
let t1 = myName1.localModule1.myVal //値は1
let t2 = myName1.localModule2.myVal //値は2
 
それでは次を実行するとどうなるでしょうか。
 
(使用する側)
open myName1.localModule1
open myName1.localModule2
let t = myVal
printfn "%d" t
 
参照可能なmyValがlocalModule1内とlocalModule2内の両方にあるので、エラーが出るかと思うのですが、エラーは出ずに2と表示されます。
open myName1.localModule2
open myName1.localModule1
の順でopenすると1と表示されます。どうも、後でopenしたものが優先されるようです。
これはエラーの元にもなりますので、次のような回避策が準備されています。
それは、モジュールに属性を追加して、openするのを禁止するという方法です。
たとえば上のlocalModule2の定義の前に次のように[<RequireQualifiedAccess>]属性を追加します。
 
[<RequireQualifiedAccess>]
module localModule2 =
    let myVal = 2
 
これで、dllファイルをつくり、使用する側で、
open myName1.localModule2
とすると、エラーが発生します。
(もちろんmyName1.localModule2.myValという形では、参照できます。)
 
 
最後に、「ある名前空間を使用するときには、特定のモジュールを自動的にopenさせる」という属性もあるので、これを紹介しておきます。上の例では名前空間名はmyName1でした。localModule1に[<AutoOpen>]属性を付けてみます。
 
namespace myName1
 
[<AutoOpen>]
module localModule1 =
    let myVal = 1
 
[<RequireQualifiedAccess>]
module localModule2 =
    let myVal = 2
 
これでdllファイルをつくり、使用する側で
  open myName1  
  let t1 = myVal 
 
とすると、myName1名前空間をopenした段階で、localModule1は自動的にopenしているので、myValの値が参照可能となっています。
スポンサーサイト

テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

プロフィール

T GYOUTEN

Author:T GYOUTEN
F#と英単語とフリーソフトと読書に興味があります。
ホームページでフリーソフトも公開しています。どぞ御贔屓に。

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
フリーエリア
フリーエリア
blogram投票ボタン
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。